nostr 0.2.0 → 0.4.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.
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Nostr
4
+ # Classes of event kinds.
5
+ module Events
6
+ # An event whose +content+ is encrypted. It can only be decrypted by the owner of the private key that pairs
7
+ # the event's +pubkey+.
8
+ class EncryptedDirectMessage < Event
9
+ # Instantiates a new encrypted direct message
10
+ #
11
+ # @api public
12
+ #
13
+ # @example Instantiating a new encrypted direct message
14
+ # Nostr::Events::EncryptedDirectMessage.new(
15
+ # sender_private_key: 'ccf9fdf3e1466d7c20969c71ec98defcf5f54aee088513e1b73ccb7bd770d460',
16
+ # recipient_public_key: '48df4af6e240ac5f7c5de89bf5941b249880be0e87d03685b178ccb1a315f52e',
17
+ # plain_text: 'Your feedback is appreciated, now pay $8',
18
+ # )
19
+ #
20
+ # @example Instantiating a new encrypted direct message that references a previous direct message
21
+ # Nostr::Events::EncryptedDirectMessage.new(
22
+ # sender_private_key: 'ccf9fdf3e1466d7c20969c71ec98defcf5f54aee088513e1b73ccb7bd770d460',
23
+ # recipient_public_key: '48df4af6e240ac5f7c5de89bf5941b249880be0e87d03685b178ccb1a315f52e',
24
+ # plain_text: 'Your feedback is appreciated, now pay $8',
25
+ # previous_direct_message: 'ccf9fdf3e1466d7c20969c71ec98defcf5f54aee088513e1b73ccb7bd770d460'
26
+ # )
27
+ #
28
+ # @param plain_text [String] The +content+ of the encrypted message.
29
+ # @param sender_private_key [String] 32-bytes hex-encoded private key of the message's author.
30
+ # @param recipient_public_key [String] 32-bytes hex-encoded public key of the recipient of the encrypted message.
31
+ # @param previous_direct_message [String] 32-bytes hex-encoded id identifying the previous message in a
32
+ # conversation or a message we are explicitly replying to (such that contextual, more organized conversations
33
+ # may happen
34
+ #
35
+ def initialize(plain_text:, sender_private_key:, recipient_public_key:, previous_direct_message: nil)
36
+ crypto = Crypto.new
37
+ keygen = Keygen.new
38
+
39
+ encrypted_content = crypto.encrypt_text(sender_private_key, recipient_public_key, plain_text)
40
+ sender_public_key = keygen.extract_public_key(sender_private_key)
41
+
42
+ super(
43
+ pubkey: sender_public_key,
44
+ kind: Nostr::EventKind::ENCRYPTED_DIRECT_MESSAGE,
45
+ content: encrypted_content,
46
+ )
47
+
48
+ add_pubkey_reference(recipient_public_key)
49
+ add_event_reference(previous_direct_message) if previous_direct_message
50
+ end
51
+ end
52
+ end
53
+ end
data/lib/nostr/keygen.rb CHANGED
@@ -62,7 +62,7 @@ module Nostr
62
62
  # @return [String] A 32-bytes hex-encoded public key.
63
63
  #
64
64
  def extract_public_key(private_key)
65
- group.generator.multiply_by_scalar(private_key.to_i(16)).x.to_s(16)
65
+ group.generator.multiply_by_scalar(private_key.to_i(16)).x.to_s(16).rjust(64, '0')
66
66
  end
67
67
 
68
68
  private
data/lib/nostr/user.rb CHANGED
@@ -50,43 +50,15 @@ module Nostr
50
50
  # @param event_attributes [Hash]
51
51
  # @option event_attributes [String] :pubkey 32-bytes hex-encoded public key of the event creator.
52
52
  # @option event_attributes [Integer] :created_at Date of the creation of the vent. A UNIX timestamp, in seconds.
53
- # @option event_attributes [Integer] :kind The kind of the event. An integer from 0 to 2.
53
+ # @option event_attributes [Integer] :kind The kind of the event. An integer from 0 to 3.
54
54
  # @option event_attributes [Array<Array>] :tags An array of tags. Each tag is an array of strings.
55
55
  # @option event_attributes [String] :content Arbitrary string.
56
56
  #
57
57
  # @return [Event]
58
58
  #
59
59
  def create_event(event_attributes)
60
- event_fragment = EventFragment.new(**event_attributes.merge(pubkey: keypair.public_key))
61
- event_sha256 = Digest::SHA256.hexdigest(JSON.dump(event_fragment.serialize))
62
-
63
- signature = sign(event_sha256)
64
-
65
- Event.new(
66
- id: event_sha256,
67
- pubkey: event_fragment.pubkey,
68
- created_at: event_fragment.created_at,
69
- kind: event_fragment.kind,
70
- tags: event_fragment.tags,
71
- content: event_fragment.content,
72
- sig: signature
73
- )
74
- end
75
-
76
- private
77
-
78
- # Signs an event with the user's private key
79
- #
80
- # @api private
81
- #
82
- # @param event_sha256 [String] The SHA256 hash of the event.
83
- #
84
- # @return [String] The signature of the event.
85
- #
86
- def sign(event_sha256)
87
- hex_private_key = Array(keypair.private_key).pack('H*')
88
- hex_message = Array(event_sha256).pack('H*')
89
- Schnorr.sign(hex_message, hex_private_key).encode.unpack1('H*')
60
+ event = Event.new(**event_attributes.merge(pubkey: keypair.public_key))
61
+ event.sign(keypair.private_key)
90
62
  end
91
63
  end
92
64
  end
data/lib/nostr/version.rb CHANGED
@@ -2,5 +2,5 @@
2
2
 
3
3
  module Nostr
4
4
  # The version of the gem
5
- VERSION = '0.2.0'
5
+ VERSION = '0.4.0'
6
6
  end
data/lib/nostr.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative 'nostr/crypto'
3
4
  require_relative 'nostr/version'
4
5
  require_relative 'nostr/keygen'
5
6
  require_relative 'nostr/client_message_type'
@@ -8,8 +9,8 @@ require_relative 'nostr/subscription'
8
9
  require_relative 'nostr/relay'
9
10
  require_relative 'nostr/key_pair'
10
11
  require_relative 'nostr/event_kind'
11
- require_relative 'nostr/event_fragment'
12
12
  require_relative 'nostr/event'
13
+ require_relative 'nostr/events/encrypted_direct_message'
13
14
  require_relative 'nostr/client'
14
15
  require_relative 'nostr/user'
15
16
 
data/nostr.gemspec CHANGED
@@ -50,12 +50,15 @@ Gem::Specification.new do |spec|
50
50
  spec.add_development_dependency 'puma', '~> 5.6'
51
51
  spec.add_development_dependency 'rack', '~> 3.0'
52
52
  spec.add_development_dependency 'rake', '~> 13.0'
53
+ spec.add_development_dependency 'rbs', '~> 2.8'
53
54
  spec.add_development_dependency 'rspec', '~> 3.12'
54
55
  spec.add_development_dependency 'rubocop', '~> 1.42'
55
56
  spec.add_development_dependency 'rubocop-rake', '~> 0.6'
56
57
  spec.add_development_dependency 'rubocop-rspec', '2.16'
57
58
  spec.add_development_dependency 'simplecov', '= 0.17'
58
59
  spec.add_development_dependency 'simplecov-console', '~> 0.9'
60
+ spec.add_development_dependency 'steep', '~> 1.3'
61
+ spec.add_development_dependency 'typeprof', '~> 0.21'
59
62
  spec.add_development_dependency 'yard', '~> 0.9'
60
63
  spec.add_development_dependency 'yard-junk', '~> 0.0.9'
61
64
  spec.add_development_dependency 'yardstick', '~> 0.9'
@@ -0,0 +1,20 @@
1
+ module Nostr
2
+ class Client
3
+ include EventEmitter
4
+
5
+ def initialize: -> void
6
+ def connect: (Relay relay) -> Thread
7
+ def subscribe: (?subscription_id: String, ?filter: Filter) -> Subscription
8
+ def unsubscribe: (String subscription_id) -> untyped
9
+ def publish: (Event event) -> untyped
10
+
11
+ private
12
+
13
+ attr_reader subscriptions: Hash[String, Subscription]
14
+ attr_reader parent_to_child_channel: untyped
15
+ attr_reader child_to_parent_channel: untyped
16
+
17
+ def execute_within_an_em_thread: { -> untyped } -> Thread
18
+ def initialize_channels: -> untyped
19
+ end
20
+ end
@@ -0,0 +1,7 @@
1
+ module Nostr
2
+ module ClientMessageType
3
+ EVENT: String
4
+ REQ: String
5
+ CLOSE: String
6
+ end
7
+ end
@@ -0,0 +1,16 @@
1
+ module Nostr
2
+ class Crypto
3
+ BN_BASE: Integer
4
+ CIPHER_CURVE: String
5
+ CIPHER_ALGORITHM: String
6
+
7
+ def encrypt_text: (String, String, String) -> String
8
+ def decrypt_text: (String, String, String) -> String
9
+ def sign_event: (Event, String) -> Event
10
+
11
+ private
12
+
13
+ def compute_shared_key: (String, String) -> String
14
+ def hash_event:(Event) -> String
15
+ end
16
+ end
@@ -0,0 +1,39 @@
1
+ module Nostr
2
+ class Event
3
+ attr_reader pubkey: String
4
+ attr_reader created_at: Integer
5
+ attr_reader kind: Integer
6
+ attr_reader tags: Array[Array[String]]
7
+ attr_reader content: String
8
+ attr_accessor id: String?|nil
9
+ attr_accessor sig: String?|nil
10
+
11
+ def initialize: (
12
+ pubkey: String,
13
+ kind: Integer,
14
+ content: String,
15
+ ?created_at: Integer,
16
+ ?tags: Array[Array[String]],
17
+ ?id: String|nil,
18
+ ?sig: String|nil
19
+ ) -> void
20
+
21
+ def serialize: -> [Integer, String, Integer, Integer, Array[Array[String]], String]
22
+
23
+ def to_h: -> {
24
+ id: String?|nil,
25
+ pubkey: String,
26
+ created_at: Integer,
27
+ kind: Integer,
28
+ tags: Array[Array[String]],
29
+ content: String,
30
+ sig: String?|nil
31
+ }
32
+ def ==: (Event other) -> bool
33
+
34
+ def sign:(String) -> Event
35
+
36
+ def add_event_reference: (String) -> Array[Array[String]]
37
+ def add_pubkey_reference: (String) -> Array[Array[String]]
38
+ end
39
+ end
@@ -0,0 +1,9 @@
1
+ module Nostr
2
+ module EventKind
3
+ SET_METADATA: Integer
4
+ TEXT_NOTE: Integer
5
+ RECOMMEND_SERVER: Integer
6
+ CONTACT_LIST: Integer
7
+ ENCRYPTED_DIRECT_MESSAGE: Integer
8
+ end
9
+ end
@@ -0,0 +1,12 @@
1
+ module Nostr
2
+ module Events
3
+ class EncryptedDirectMessage < Event
4
+ def initialize: (
5
+ plain_text: String,
6
+ sender_private_key: String,
7
+ recipient_public_key: String,
8
+ ?previous_direct_message: String|nil
9
+ ) -> void
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,25 @@
1
+ module Nostr
2
+ class Filter
3
+ attr_reader ids: Array[String]
4
+ attr_reader authors: Array[String]
5
+ attr_reader kinds: Array[Integer]
6
+ attr_reader e: String
7
+ attr_reader p: String
8
+ attr_reader since: Integer
9
+ attr_reader until: Integer
10
+ attr_reader limit: Integer
11
+
12
+ def initialize: (**untyped) -> void
13
+ def to_h: -> {
14
+ ids: Array[String],
15
+ authors: Array[String],
16
+ kinds: Array[Integer],
17
+ e: String,
18
+ p: String,
19
+ since: Integer,
20
+ until: Integer,
21
+ limit: Integer
22
+ }
23
+ def ==: (Filter other) -> bool
24
+ end
25
+ end
@@ -0,0 +1,9 @@
1
+ # Classes
2
+ module Nostr
3
+ class KeyPair
4
+ attr_reader private_key: String
5
+ attr_reader public_key: String
6
+
7
+ def initialize: (private_key: String, public_key: String) -> void
8
+ end
9
+ end
@@ -0,0 +1,13 @@
1
+ # Classes
2
+ module Nostr
3
+ class Keygen
4
+ def initialize: -> void
5
+ def generate_key_pair: -> KeyPair
6
+ def generate_private_key: -> String
7
+ def extract_public_key: (String private_key) -> String
8
+
9
+ private
10
+
11
+ attr_reader group: untyped
12
+ end
13
+ end
@@ -0,0 +1,9 @@
1
+ # Classes
2
+ module Nostr
3
+ class Relay
4
+ attr_reader url: String
5
+ attr_reader name: String
6
+
7
+ def initialize: (url: String, name: String) -> void
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ module Nostr
2
+ class Subscription
3
+ attr_reader id: String
4
+ attr_reader filter: Filter
5
+
6
+ def initialize: (filter: Filter, ?id: String) -> void
7
+ def ==: (Subscription other) -> bool
8
+ end
9
+ end
@@ -0,0 +1,22 @@
1
+ # Classes
2
+ module Nostr
3
+ class User
4
+ attr_reader keypair: KeyPair
5
+
6
+ def initialize: (?keypair: KeyPair | nil, ?keygen: Keygen) -> void
7
+ def create_event: (
8
+ {
9
+ pubkey: String,
10
+ created_at: Integer,
11
+ kind: Integer,
12
+ tags: Array[String],
13
+ content: String,
14
+ created_at: Integer,
15
+ }
16
+ ) -> Event
17
+
18
+ private
19
+
20
+ def sign: (String event_sha256) -> String
21
+ end
22
+ end
@@ -0,0 +1,6 @@
1
+ # Added only to satisfy the Steep requirements. Not 100% reliable.
2
+ module ECDSA
3
+ class Group
4
+ Secp256k1: Group
5
+ end
6
+ end
@@ -0,0 +1,9 @@
1
+ # Added only to satisfy the Steep requirements. Not 100% reliable.
2
+ module EventEmitter
3
+ def add_listener: (untyped `type`, ?{once: true} params) -> Integer
4
+ alias on add_listener
5
+
6
+ def remove_listener: (untyped id_or_type) -> Array[untyped]?
7
+ def emit: (untyped `type`, *untyped data) -> Array[untyped]
8
+ def once: (untyped `type`) -> Integer
9
+ end
@@ -0,0 +1,18 @@
1
+ # Added only to satisfy the Steep requirements. Not 100% reliable.
2
+ module EventMachine
3
+ class Channel
4
+ @subs: Hash[untyped, untyped]
5
+ @uid: Integer
6
+
7
+ def initialize: -> void
8
+ def num_subscribers: -> Integer
9
+ def subscribe: (*untyped a) ?{ -> untyped } -> Integer
10
+ def unsubscribe: (untyped name) -> untyped
11
+ def push: (*untyped items) -> untyped
12
+ alias << push
13
+ def pop: (*untyped a) -> untyped
14
+
15
+ private
16
+ def gen_id: -> Integer
17
+ end
18
+ end
@@ -0,0 +1,69 @@
1
+ # Added only to satisfy the Steep requirements. Not 100% reliable.
2
+ module EventMachine
3
+ ERRNOS: Hash[untyped, untyped]
4
+ P: untyped
5
+ self.@next_tick_mutex: Thread::Mutex
6
+ self.@reactor_running: bool
7
+ self.@next_tick_queue: Array[^-> untyped]
8
+ self.@tails: Array[nil]
9
+ self.@resultqueue: (Array[untyped] | Thread::Queue)?
10
+ self.@threadqueue: Thread::Queue?
11
+ self.@threadpool: Array[untyped]?
12
+ self.@all_threads_spawned: bool
13
+ self.@reactor_pid: Integer
14
+ self.@conns: Hash[untyped, untyped]
15
+ self.@acceptors: Hash[untyped, Array[(Array[untyped] | Integer)?]]
16
+ self.@timers: Hash[untyped, Integer | ^-> untyped | false]
17
+ self.@wrapped_exception: Exception?
18
+ self.@reactor_thread: Thread?
19
+ self.@threadpool_size: bot
20
+ self.@error_handler: bot
21
+
22
+ def self.run: (?untyped blk, ?nil tail) ?{ -> untyped } -> nil
23
+ def self.run_block: -> nil
24
+ def self.reactor_thread?: -> bool
25
+ def self.schedule: (*untyped a) -> nil
26
+ def self.fork_reactor: -> Integer?
27
+ def self.cleanup_machine: -> Array[untyped]
28
+ def self.add_shutdown_hook: -> Array[nil]
29
+ def self.add_timer: (*Integer | ^-> untyped args) ?{ -> untyped } -> nil
30
+ def self.add_periodic_timer: (*untyped args) -> untyped
31
+ def self.cancel_timer: (untyped timer_or_sig) -> false?
32
+ def self.stop_event_loop: -> untyped
33
+ def self.start_server: (untyped server, ?nil port, ?nil handler, *untyped args) -> untyped
34
+ def self.attach_server: (untyped sock, ?nil handler, *untyped args) -> untyped
35
+ def self.stop_server: (untyped signature) -> untyped
36
+ def self.start_unix_domain_server: (untyped filename, *untyped args) -> untyped
37
+ def self.connect: (untyped server, ?nil port, ?nil handler, *untyped args) -> untyped
38
+ def self.bind_connect: (nil bind_addr, nil bind_port, untyped server, ?nil port, ?nil handler, *untyped args) -> untyped
39
+ def self.watch: (untyped io, ?nil handler, *untyped args) -> untyped
40
+ def self.attach: (untyped io, ?nil handler, *untyped args) -> untyped
41
+ def self.attach_io: (untyped io, bool watch_mode, ?nil handler, *untyped args) -> untyped
42
+ def self.reconnect: (untyped server, untyped port, untyped handler) -> untyped
43
+ def self.connect_unix_domain: (untyped socketname, *untyped args) -> untyped
44
+ def self.open_datagram_socket: (untyped address, untyped port, ?nil handler, *untyped args) -> untyped
45
+ def self.set_quantum: (untyped mills) -> untyped
46
+ def self.set_max_timers: (untyped ct) -> untyped
47
+ def self.get_max_timers: -> untyped
48
+ def self.connection_count: -> untyped
49
+ def self.run_deferred_callbacks: -> Integer
50
+ def self.defer: (?nil op, ?nil callback, ?nil errback) -> untyped
51
+ def self.spawn_threadpool: -> true
52
+ def self.defers_finished?: -> bool
53
+ def self.next_tick: (?nil pr) { -> nil } -> nil
54
+ def self.set_effective_user: (untyped username) -> untyped
55
+ def self.set_descriptor_table_size: (?nil n_descriptors) -> untyped
56
+ def self.popen: (untyped cmd, ?nil handler, *untyped args) -> untyped
57
+ def self.reactor_running?: -> bool
58
+ def self.open_keyboard: (?nil handler, *untyped args) -> untyped
59
+ def self.watch_file: (untyped filename, ?nil handler, *untyped args) -> untyped
60
+ def self.watch_process: (untyped pid, ?nil handler, *untyped args) -> untyped
61
+ def self.error_handler: (?nil cb) -> nil
62
+ def self.enable_proxy: (untyped from, untyped to, ?Integer bufsize, ?Integer length) -> untyped
63
+ def self.disable_proxy: (untyped from) -> untyped
64
+ def self.heartbeat_interval: -> untyped
65
+ def self.heartbeat_interval=: (untyped time) -> untyped
66
+ def self.event_callback: (untyped conn_binding, untyped opcode, untyped data) -> Integer?
67
+ def self._open_file_for_writing: (untyped filename, ?nil handler) -> untyped
68
+ def self.klass_from_handler: (?untyped klass, ?Integer? handler, *nil args) -> Integer
69
+ end
@@ -0,0 +1,4 @@
1
+ # Added only to satisfy the Steep requirements. Not 100% reliable.
2
+ module Schnorr
3
+ def self.sign: (String message, String private_key, ?String aux_rand) -> untyped
4
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nostr
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Wilson Silva
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-01-12 00:00:00.000000000 Z
11
+ date: 2023-02-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bech32
@@ -262,6 +262,20 @@ dependencies:
262
262
  - - "~>"
263
263
  - !ruby/object:Gem::Version
264
264
  version: '13.0'
265
+ - !ruby/object:Gem::Dependency
266
+ name: rbs
267
+ requirement: !ruby/object:Gem::Requirement
268
+ requirements:
269
+ - - "~>"
270
+ - !ruby/object:Gem::Version
271
+ version: '2.8'
272
+ type: :development
273
+ prerelease: false
274
+ version_requirements: !ruby/object:Gem::Requirement
275
+ requirements:
276
+ - - "~>"
277
+ - !ruby/object:Gem::Version
278
+ version: '2.8'
265
279
  - !ruby/object:Gem::Dependency
266
280
  name: rspec
267
281
  requirement: !ruby/object:Gem::Requirement
@@ -346,6 +360,34 @@ dependencies:
346
360
  - - "~>"
347
361
  - !ruby/object:Gem::Version
348
362
  version: '0.9'
363
+ - !ruby/object:Gem::Dependency
364
+ name: steep
365
+ requirement: !ruby/object:Gem::Requirement
366
+ requirements:
367
+ - - "~>"
368
+ - !ruby/object:Gem::Version
369
+ version: '1.3'
370
+ type: :development
371
+ prerelease: false
372
+ version_requirements: !ruby/object:Gem::Requirement
373
+ requirements:
374
+ - - "~>"
375
+ - !ruby/object:Gem::Version
376
+ version: '1.3'
377
+ - !ruby/object:Gem::Dependency
378
+ name: typeprof
379
+ requirement: !ruby/object:Gem::Requirement
380
+ requirements:
381
+ - - "~>"
382
+ - !ruby/object:Gem::Version
383
+ version: '0.21'
384
+ type: :development
385
+ prerelease: false
386
+ version_requirements: !ruby/object:Gem::Requirement
387
+ requirements:
388
+ - - "~>"
389
+ - !ruby/object:Gem::Version
390
+ version: '0.21'
349
391
  - !ruby/object:Gem::Dependency
350
392
  name: yard
351
393
  requirement: !ruby/object:Gem::Requirement
@@ -409,12 +451,14 @@ files:
409
451
  - LICENSE.txt
410
452
  - README.md
411
453
  - Rakefile
454
+ - Steepfile
412
455
  - lib/nostr.rb
413
456
  - lib/nostr/client.rb
414
457
  - lib/nostr/client_message_type.rb
458
+ - lib/nostr/crypto.rb
415
459
  - lib/nostr/event.rb
416
- - lib/nostr/event_fragment.rb
417
460
  - lib/nostr/event_kind.rb
461
+ - lib/nostr/events/encrypted_direct_message.rb
418
462
  - lib/nostr/filter.rb
419
463
  - lib/nostr/key_pair.rb
420
464
  - lib/nostr/keygen.rb
@@ -424,6 +468,23 @@ files:
424
468
  - lib/nostr/version.rb
425
469
  - nostr.gemspec
426
470
  - sig/nostr.rbs
471
+ - sig/nostr/client.rbs
472
+ - sig/nostr/client_message_type.rbs
473
+ - sig/nostr/crypto.rbs
474
+ - sig/nostr/event.rbs
475
+ - sig/nostr/event_kind.rbs
476
+ - sig/nostr/events/encrypted_direct_message.rbs
477
+ - sig/nostr/filter.rbs
478
+ - sig/nostr/key_pair.rbs
479
+ - sig/nostr/keygen.rbs
480
+ - sig/nostr/relay.rbs
481
+ - sig/nostr/subscription.rbs
482
+ - sig/nostr/user.rbs
483
+ - sig/vendor/ecsda/group/secp256k1.rbs
484
+ - sig/vendor/event_emitter.rbs
485
+ - sig/vendor/event_machine.rbs
486
+ - sig/vendor/event_machine/channel.rbs
487
+ - sig/vendor/schnorr.rbs
427
488
  homepage: https://github.com/wilsonsilva/nostr
428
489
  licenses:
429
490
  - MIT
@@ -447,7 +508,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
447
508
  - !ruby/object:Gem::Version
448
509
  version: '0'
449
510
  requirements: []
450
- rubygems_version: 3.4.1
511
+ rubygems_version: 3.4.7
451
512
  signing_key:
452
513
  specification_version: 4
453
514
  summary: Client and relay implementation of the Nostr protocol.