nostr 0.4.0 → 0.5.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.
Files changed (87) hide show
  1. checksums.yaml +4 -4
  2. data/.editorconfig +1 -1
  3. data/.rubocop.yml +23 -0
  4. data/.tool-versions +2 -1
  5. data/CHANGELOG.md +36 -1
  6. data/README.md +92 -228
  7. data/docs/.gitignore +4 -0
  8. data/docs/.vitepress/config.mjs +112 -0
  9. data/docs/README.md +44 -0
  10. data/docs/api-examples.md +49 -0
  11. data/docs/bun.lockb +0 -0
  12. data/docs/common-use-cases/bech32-encoding-and-decoding-(NIP-19).md +190 -0
  13. data/docs/core/client.md +108 -0
  14. data/docs/core/keys.md +136 -0
  15. data/docs/core/user.md +43 -0
  16. data/docs/events/contact-list.md +29 -0
  17. data/docs/events/encrypted-direct-message.md +28 -0
  18. data/docs/events/recommend-server.md +32 -0
  19. data/docs/events/set-metadata.md +20 -0
  20. data/docs/events/text-note.md +15 -0
  21. data/docs/events.md +11 -0
  22. data/docs/getting-started/installation.md +21 -0
  23. data/docs/getting-started/overview.md +170 -0
  24. data/docs/implemented-nips.md +9 -0
  25. data/docs/index.md +44 -0
  26. data/docs/markdown-examples.md +85 -0
  27. data/docs/package.json +12 -0
  28. data/docs/relays/connecting-to-a-relay.md +21 -0
  29. data/docs/relays/publishing-events.md +29 -0
  30. data/docs/relays/receiving-events.md +6 -0
  31. data/docs/subscriptions/creating-a-subscription.md +49 -0
  32. data/docs/subscriptions/deleting-a-subscription.md +10 -0
  33. data/docs/subscriptions/filtering-subscription-events.md +115 -0
  34. data/docs/subscriptions/updating-a-subscription.md +4 -0
  35. data/lib/nostr/bech32.rb +203 -0
  36. data/lib/nostr/client.rb +2 -1
  37. data/lib/nostr/crypto.rb +11 -7
  38. data/lib/nostr/errors/error.rb +7 -0
  39. data/lib/nostr/errors/invalid_hrp_error.rb +21 -0
  40. data/lib/nostr/errors/invalid_key_format_error.rb +20 -0
  41. data/lib/nostr/errors/invalid_key_length_error.rb +20 -0
  42. data/lib/nostr/errors/invalid_key_type_error.rb +18 -0
  43. data/lib/nostr/errors/key_validation_error.rb +6 -0
  44. data/lib/nostr/errors.rb +8 -0
  45. data/lib/nostr/event.rb +3 -4
  46. data/lib/nostr/events/encrypted_direct_message.rb +4 -3
  47. data/lib/nostr/filter.rb +4 -4
  48. data/lib/nostr/key.rb +100 -0
  49. data/lib/nostr/key_pair.rb +30 -6
  50. data/lib/nostr/keygen.rb +43 -4
  51. data/lib/nostr/private_key.rb +36 -0
  52. data/lib/nostr/public_key.rb +36 -0
  53. data/lib/nostr/relay_message_type.rb +18 -0
  54. data/lib/nostr/subscription.rb +2 -2
  55. data/lib/nostr/user.rb +17 -8
  56. data/lib/nostr/version.rb +1 -1
  57. data/lib/nostr.rb +6 -0
  58. data/nostr.gemspec +9 -9
  59. data/sig/nostr/bech32.rbs +14 -0
  60. data/sig/nostr/client.rbs +5 -5
  61. data/sig/nostr/crypto.rbs +5 -5
  62. data/sig/nostr/errors/error.rbs +4 -0
  63. data/sig/nostr/errors/invalid_hrb_error.rbs +6 -0
  64. data/sig/nostr/errors/invalid_key_format_error.rbs +5 -0
  65. data/sig/nostr/errors/invalid_key_length_error.rbs +5 -0
  66. data/sig/nostr/errors/invalid_key_type_error.rbs +5 -0
  67. data/sig/nostr/errors/key_validation_error.rbs +4 -0
  68. data/sig/nostr/event.rbs +4 -4
  69. data/sig/nostr/events/encrypted_direct_message.rbs +2 -2
  70. data/sig/nostr/filter.rbs +3 -12
  71. data/sig/nostr/key.rbs +16 -0
  72. data/sig/nostr/key_pair.rbs +7 -3
  73. data/sig/nostr/keygen.rbs +5 -2
  74. data/sig/nostr/private_key.rbs +4 -0
  75. data/sig/nostr/public_key.rbs +4 -0
  76. data/sig/nostr/relay_message_type.rbs +8 -0
  77. data/sig/nostr/user.rbs +4 -8
  78. data/sig/vendor/bech32/nostr/entity.rbs +41 -0
  79. data/sig/vendor/bech32/nostr/nip19.rbs +20 -0
  80. data/sig/vendor/bech32/segwit_addr.rbs +21 -0
  81. data/sig/vendor/bech32.rbs +25 -0
  82. data/sig/vendor/event_emitter.rbs +10 -3
  83. data/sig/vendor/event_machine/channel.rbs +1 -1
  84. data/sig/vendor/faye/websocket/api.rbs +45 -0
  85. data/sig/vendor/faye/websocket/client.rbs +43 -0
  86. data/sig/vendor/faye/websocket.rbs +30 -0
  87. metadata +79 -21
data/lib/nostr/keygen.rb CHANGED
@@ -44,10 +44,11 @@ module Nostr
44
44
  # private_key = keygen.generate_private_key
45
45
  # private_key # => '893c4cc8088924796b41dc788f7e2f746734497010b1a9f005c1faad7074b900'
46
46
  #
47
- # @return [String] A 32-bytes hex-encoded private key.
47
+ # @return [PrivateKey] A 32-bytes hex-encoded private key.
48
48
  #
49
49
  def generate_private_key
50
- (SecureRandom.random_number(group.order - 1) + 1).to_s(16)
50
+ hex_value = (SecureRandom.random_number(group.order - 1) + 1).to_s(16).rjust(64, '0')
51
+ PrivateKey.new(hex_value)
51
52
  end
52
53
 
53
54
  # Extracts a public key from a private key
@@ -59,10 +60,36 @@ module Nostr
59
60
  # public_key = keygen.extract_public_key(private_key)
60
61
  # public_key # => '2d7661527d573cc8e84f665fa971dd969ba51e2526df00c149ff8e40a58f9558'
61
62
  #
62
- # @return [String] A 32-bytes hex-encoded public key.
63
+ # @param [PrivateKey] private_key A 32-bytes hex-encoded private key.
64
+ #
65
+ # @raise [ArgumentError] if the private key is not an instance of +PrivateKey+
66
+ #
67
+ # @return [PublicKey] A 32-bytes hex-encoded public key.
63
68
  #
64
69
  def extract_public_key(private_key)
65
- group.generator.multiply_by_scalar(private_key.to_i(16)).x.to_s(16).rjust(64, '0')
70
+ validate_private_key(private_key)
71
+ hex_value = group.generator.multiply_by_scalar(private_key.to_i(16)).x.to_s(16).rjust(64, '0')
72
+ PublicKey.new(hex_value)
73
+ end
74
+
75
+ # Builds a key pair from an existing private key
76
+ #
77
+ # @api public
78
+ #
79
+ # @example
80
+ # private_key = Nostr::PrivateKey.new('893c4cc8088924796b41dc788f7e2f746734497010b1a9f005c1faad7074b900')
81
+ # keygen.get_key_pair_from_private_key(private_key)
82
+ #
83
+ # @param private_key [PrivateKey] 32-bytes hex-encoded private key.
84
+ #
85
+ # @raise [ArgumentError] if the private key is not an instance of +PrivateKey+
86
+ #
87
+ # @return [Nostr::KeyPair]
88
+ #
89
+ def get_key_pair_from_private_key(private_key)
90
+ validate_private_key(private_key)
91
+ public_key = extract_public_key(private_key)
92
+ KeyPair.new(private_key:, public_key:)
66
93
  end
67
94
 
68
95
  private
@@ -74,5 +101,17 @@ module Nostr
74
101
  # @return [ECDSA::Group]
75
102
  #
76
103
  attr_reader :group
104
+
105
+ # Validates that the private key is an instance of +PrivateKey+
106
+ #
107
+ # @api private
108
+ #
109
+ # @raise [ArgumentError] if the private key is not an instance of +PrivateKey+
110
+ #
111
+ # @return [void]
112
+ #
113
+ def validate_private_key(private_key)
114
+ raise ArgumentError, 'private_key is not an instance of PrivateKey' unless private_key.is_a?(Nostr::PrivateKey)
115
+ end
77
116
  end
78
117
  end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Nostr
4
+ # 32-bytes lowercase hex-encoded private key
5
+ class PrivateKey < Key
6
+ # Human-readable part of the Bech32 encoded address
7
+ #
8
+ # @api private
9
+ #
10
+ # @return [String] The human-readable part of the Bech32 encoded address
11
+ #
12
+ def self.hrp
13
+ 'nsec'
14
+ end
15
+
16
+ private
17
+
18
+ # Validates the hex value of the private key
19
+ #
20
+ # @api private
21
+ #
22
+ # @param [String] hex_value The private key in hex format
23
+ #
24
+ # @raise InvalidKeyTypeError when the private key is not a string
25
+ # @raise InvalidKeyLengthError when the private key's length is not 64 characters
26
+ # @raise InvalidKeyFormatError when the private key is in an invalid format
27
+ #
28
+ # @return [void]
29
+ #
30
+ def validate_hex_value(hex_value)
31
+ raise InvalidKeyTypeError, 'private' unless hex_value.is_a?(String)
32
+ raise InvalidKeyLengthError, 'private' unless hex_value.size == Key::LENGTH
33
+ raise InvalidKeyFormatError, 'private' unless hex_value.match(Key::FORMAT)
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Nostr
4
+ # 32-bytes lowercase hex-encoded public key
5
+ class PublicKey < Key
6
+ # Human-readable part of the Bech32 encoded address
7
+ #
8
+ # @api private
9
+ #
10
+ # @return [String] The human-readable part of the Bech32 encoded address
11
+ #
12
+ def self.hrp
13
+ 'npub'
14
+ end
15
+
16
+ private
17
+
18
+ # Validates the hex value of the public key
19
+ #
20
+ # @api private
21
+ #
22
+ # @param [String] hex_value The public key in hex format
23
+ #
24
+ # @raise InvalidKeyTypeError when the public key is not a string
25
+ # @raise InvalidKeyLengthError when the public key's length is not 64 characters
26
+ # @raise InvalidKeyFormatError when the public key is in an invalid format
27
+ #
28
+ # @return [void]
29
+ #
30
+ def validate_hex_value(hex_value)
31
+ raise InvalidKeyTypeError, 'public' unless hex_value.is_a?(String)
32
+ raise InvalidKeyLengthError, 'public' unless hex_value.size == Key::LENGTH
33
+ raise InvalidKeyFormatError, 'public' unless hex_value.match(Key::FORMAT)
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Nostr
4
+ # Clients can send 4 types of messages, which must be JSON arrays
5
+ module RelayMessageType
6
+ # @return [String] Used to notify clients all stored events have been sent
7
+ EOSE = 'EOSE'
8
+
9
+ # @return [String] Used to send events requested to clients
10
+ EVENT = 'EVENT'
11
+
12
+ # @return [String] Used to send human-readable messages to clients
13
+ NOTICE = 'NOTICE'
14
+
15
+ # @return [String] Used to notify clients if an EVENT was successful
16
+ OK = 'OK'
17
+ end
18
+ end
@@ -5,7 +5,7 @@ require 'securerandom'
5
5
  module Nostr
6
6
  # A subscription the result of a request to receive events from a relay
7
7
  class Subscription
8
- # A random string that should be used to represent a subscription
8
+ # An arbitrary, non-empty string of max length 64 chars used to represent a subscription
9
9
  #
10
10
  # @api public
11
11
  #
@@ -41,7 +41,7 @@ module Nostr
41
41
  # @example Subscribing to all events created after a certain time
42
42
  # subscription = Nostr::Subscription.new(filter: Nostr::Filter.new(since: 1230981305))
43
43
  #
44
- # @param id [String] A random string that should be used to represent a subscription
44
+ # @param id [String] An arbitrary, non-empty string of max length 64 chars used to represent a subscription
45
45
  # @param filter [Filter] An object that determines what events will be sent in that subscription
46
46
  #
47
47
  def initialize(filter:, id: SecureRandom.hex)
data/lib/nostr/user.rb CHANGED
@@ -47,17 +47,26 @@ module Nostr
47
47
  # content: 'Your feedback is appreciated, now pay $8'
48
48
  # )
49
49
  #
50
- # @param event_attributes [Hash]
51
- # @option event_attributes [String] :pubkey 32-bytes hex-encoded public key of the event creator.
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 3.
54
- # @option event_attributes [Array<Array>] :tags An array of tags. Each tag is an array of strings.
55
- # @option event_attributes [String] :content Arbitrary string.
50
+ # @param created_at [Integer] Date of the creation of the vent. A UNIX timestamp, in seconds.
51
+ # @param kind [Integer] The kind of the event. An integer from 0 to 3.
52
+ # @param tags [Array<Array>] An array of tags. Each tag is an array of strings.
53
+ # @param content [String] Arbitrary string.
56
54
  #
57
55
  # @return [Event]
58
56
  #
59
- def create_event(event_attributes)
60
- event = Event.new(**event_attributes.merge(pubkey: keypair.public_key))
57
+ def create_event(
58
+ kind:,
59
+ content:,
60
+ created_at: Time.now.to_i,
61
+ tags: []
62
+ )
63
+ event = Event.new(
64
+ pubkey: keypair.public_key,
65
+ kind:,
66
+ content:,
67
+ created_at:,
68
+ tags:
69
+ )
61
70
  event.sign(keypair.private_key)
62
71
  end
63
72
  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.4.0'
5
+ VERSION = '0.5.0'
6
6
  end
data/lib/nostr.rb CHANGED
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative 'nostr/errors'
4
+ require_relative 'nostr/bech32'
3
5
  require_relative 'nostr/crypto'
4
6
  require_relative 'nostr/version'
5
7
  require_relative 'nostr/keygen'
@@ -7,12 +9,16 @@ require_relative 'nostr/client_message_type'
7
9
  require_relative 'nostr/filter'
8
10
  require_relative 'nostr/subscription'
9
11
  require_relative 'nostr/relay'
12
+ require_relative 'nostr/relay_message_type'
10
13
  require_relative 'nostr/key_pair'
11
14
  require_relative 'nostr/event_kind'
12
15
  require_relative 'nostr/event'
13
16
  require_relative 'nostr/events/encrypted_direct_message'
14
17
  require_relative 'nostr/client'
15
18
  require_relative 'nostr/user'
19
+ require_relative 'nostr/key'
20
+ require_relative 'nostr/private_key'
21
+ require_relative 'nostr/public_key'
16
22
 
17
23
  # Encapsulates all the gem's logic
18
24
  module Nostr
data/nostr.gemspec CHANGED
@@ -10,7 +10,7 @@ Gem::Specification.new do |spec|
10
10
 
11
11
  spec.summary = 'Client and relay implementation of the Nostr protocol.'
12
12
  spec.description = 'Client and relay implementation of the Nostr protocol.'
13
- spec.homepage = 'https://github.com/wilsonsilva/nostr'
13
+ spec.homepage = 'https://nostr-ruby.com/'
14
14
  spec.license = 'MIT'
15
15
  spec.required_ruby_version = '>= 3.2.0'
16
16
  spec.metadata['rubygems_mfa_required'] = 'true'
@@ -31,8 +31,8 @@ Gem::Specification.new do |spec|
31
31
  spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
32
32
  spec.require_paths = ['lib']
33
33
 
34
- spec.add_dependency 'bech32', '~> 1.3'
35
- spec.add_dependency 'bip-schnorr', '~> 0.4'
34
+ spec.add_dependency 'bech32', '~> 1.4'
35
+ spec.add_dependency 'bip-schnorr', '~> 0.6'
36
36
  spec.add_dependency 'ecdsa', '~> 1.2'
37
37
  spec.add_dependency 'event_emitter', '~> 0.2'
38
38
  spec.add_dependency 'faye-websocket', '~> 0.11'
@@ -47,17 +47,17 @@ Gem::Specification.new do |spec|
47
47
  spec.add_development_dependency 'guard-rubocop', '~> 1.5'
48
48
  spec.add_development_dependency 'overcommit', '~> 0.59'
49
49
  spec.add_development_dependency 'pry', '~> 0.14'
50
- spec.add_development_dependency 'puma', '~> 5.6'
50
+ spec.add_development_dependency 'puma', '~> 6.4'
51
51
  spec.add_development_dependency 'rack', '~> 3.0'
52
- spec.add_development_dependency 'rake', '~> 13.0'
53
- spec.add_development_dependency 'rbs', '~> 2.8'
52
+ spec.add_development_dependency 'rake', '~> 13.1'
53
+ spec.add_development_dependency 'rbs', '~> 3.3'
54
54
  spec.add_development_dependency 'rspec', '~> 3.12'
55
- spec.add_development_dependency 'rubocop', '~> 1.42'
55
+ spec.add_development_dependency 'rubocop', '~> 1.57'
56
56
  spec.add_development_dependency 'rubocop-rake', '~> 0.6'
57
- spec.add_development_dependency 'rubocop-rspec', '2.16'
57
+ spec.add_development_dependency 'rubocop-rspec', '2.25'
58
58
  spec.add_development_dependency 'simplecov', '= 0.17'
59
59
  spec.add_development_dependency 'simplecov-console', '~> 0.9'
60
- spec.add_development_dependency 'steep', '~> 1.3'
60
+ spec.add_development_dependency 'steep', '~> 1.6'
61
61
  spec.add_development_dependency 'typeprof', '~> 0.21'
62
62
  spec.add_development_dependency 'yard', '~> 0.9'
63
63
  spec.add_development_dependency 'yard-junk', '~> 0.0.9'
@@ -0,0 +1,14 @@
1
+ module Nostr
2
+ module Bech32
3
+ # Perhaps a bug in RBS/Steep. +decode+ and +encode+ are not recognized as public class methods.
4
+ def self?.decode: (String data) -> [String, String]
5
+ def self?.encode: (hrp: String, data: String) -> String
6
+
7
+ def naddr_encode: (pubkey: PublicKey, ?relays: Array[String], ?kind: Integer, ?identifier: String) -> String
8
+ def nevent_encode: (id: PublicKey, ?relays: Array[String], ?kind: Integer) -> String
9
+ def nprofile_encode: (pubkey: PublicKey, ?relays: Array[String]) -> String
10
+ def npub_encode: (String npub) -> String
11
+ def nrelay_encode: (String nrelay) -> String
12
+ def nsec_encode: (String nsec) -> String
13
+ end
14
+ end
data/sig/nostr/client.rbs CHANGED
@@ -5,16 +5,16 @@ module Nostr
5
5
  def initialize: -> void
6
6
  def connect: (Relay relay) -> Thread
7
7
  def subscribe: (?subscription_id: String, ?filter: Filter) -> Subscription
8
- def unsubscribe: (String subscription_id) -> untyped
8
+ def unsubscribe: (String subscription_id) -> void
9
9
  def publish: (Event event) -> untyped
10
10
 
11
11
  private
12
12
 
13
13
  attr_reader subscriptions: Hash[String, Subscription]
14
- attr_reader parent_to_child_channel: untyped
15
- attr_reader child_to_parent_channel: untyped
14
+ attr_reader parent_to_child_channel: EventMachine::Channel
15
+ attr_reader child_to_parent_channel: EventMachine::Channel
16
16
 
17
- def execute_within_an_em_thread: { -> untyped } -> Thread
18
- def initialize_channels: -> untyped
17
+ def execute_within_an_em_thread: { -> void } -> Thread
18
+ def initialize_channels: -> void
19
19
  end
20
20
  end
data/sig/nostr/crypto.rbs CHANGED
@@ -1,16 +1,16 @@
1
1
  module Nostr
2
2
  class Crypto
3
- BN_BASE: Integer
3
+ BN_BASE: 0 | 2 | 10 | 16
4
4
  CIPHER_CURVE: String
5
5
  CIPHER_ALGORITHM: String
6
6
 
7
- def encrypt_text: (String, String, String) -> String
8
- def decrypt_text: (String, String, String) -> String
9
- def sign_event: (Event, String) -> Event
7
+ def encrypt_text: (PrivateKey, PublicKey, String) -> String
8
+ def decrypt_text: (PrivateKey, PublicKey, String) -> String
9
+ def sign_event: (Event, PrivateKey) -> Event
10
10
 
11
11
  private
12
12
 
13
- def compute_shared_key: (String, String) -> String
13
+ def compute_shared_key: (PrivateKey, PublicKey) -> String
14
14
  def hash_event:(Event) -> String
15
15
  end
16
16
  end
@@ -0,0 +1,4 @@
1
+ module Nostr
2
+ class Error < StandardError
3
+ end
4
+ end
@@ -0,0 +1,6 @@
1
+ module Nostr
2
+ class InvalidHRPError < KeyValidationError
3
+ def initialize: (String, String) -> void
4
+ end
5
+ end
6
+
@@ -0,0 +1,5 @@
1
+ module Nostr
2
+ class InvalidKeyFormatError < KeyValidationError
3
+ def initialize: (String) -> void
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ module Nostr
2
+ class InvalidKeyLengthError < KeyValidationError
3
+ def initialize: (String) -> void
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ module Nostr
2
+ class InvalidKeyTypeError < KeyValidationError
3
+ def initialize: (String) -> void
4
+ end
5
+ end
@@ -0,0 +1,4 @@
1
+ module Nostr
2
+ class KeyValidationError < Error
3
+ end
4
+ end
data/sig/nostr/event.rbs CHANGED
@@ -1,6 +1,6 @@
1
1
  module Nostr
2
2
  class Event
3
- attr_reader pubkey: String
3
+ attr_reader pubkey: PublicKey
4
4
  attr_reader created_at: Integer
5
5
  attr_reader kind: Integer
6
6
  attr_reader tags: Array[Array[String]]
@@ -9,7 +9,7 @@ module Nostr
9
9
  attr_accessor sig: String?|nil
10
10
 
11
11
  def initialize: (
12
- pubkey: String,
12
+ pubkey: PublicKey,
13
13
  kind: Integer,
14
14
  content: String,
15
15
  ?created_at: Integer,
@@ -31,9 +31,9 @@ module Nostr
31
31
  }
32
32
  def ==: (Event other) -> bool
33
33
 
34
- def sign:(String) -> Event
34
+ def sign:(PrivateKey) -> Event
35
35
 
36
36
  def add_event_reference: (String) -> Array[Array[String]]
37
- def add_pubkey_reference: (String) -> Array[Array[String]]
37
+ def add_pubkey_reference: (PublicKey) -> Array[Array[String]]
38
38
  end
39
39
  end
@@ -3,8 +3,8 @@ module Nostr
3
3
  class EncryptedDirectMessage < Event
4
4
  def initialize: (
5
5
  plain_text: String,
6
- sender_private_key: String,
7
- recipient_public_key: String,
6
+ sender_private_key: PrivateKey,
7
+ recipient_public_key: PublicKey,
8
8
  ?previous_direct_message: String|nil
9
9
  ) -> void
10
10
  end
data/sig/nostr/filter.rbs CHANGED
@@ -3,23 +3,14 @@ module Nostr
3
3
  attr_reader ids: Array[String]
4
4
  attr_reader authors: Array[String]
5
5
  attr_reader kinds: Array[Integer]
6
- attr_reader e: String
7
- attr_reader p: String
6
+ attr_reader e: Array[String]
7
+ attr_reader p: Array[String]
8
8
  attr_reader since: Integer
9
9
  attr_reader until: Integer
10
10
  attr_reader limit: Integer
11
11
 
12
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
- }
13
+ def to_h: -> Hash[::Symbol, (::Array[::String] | ::Array[::Integer] | ::Integer)]
23
14
  def ==: (Filter other) -> bool
24
15
  end
25
16
  end
data/sig/nostr/key.rbs ADDED
@@ -0,0 +1,16 @@
1
+ module Nostr
2
+ class Key < String
3
+ FORMAT: Regexp
4
+ LENGTH: int
5
+
6
+ def self.from_bech32: (String) -> Key
7
+ def self.hrp: -> String
8
+
9
+ def initialize: (String) -> void
10
+ def to_bech32: -> String
11
+
12
+ private
13
+
14
+ def validate_hex_value: (String) -> nil
15
+ end
16
+ end
@@ -1,9 +1,13 @@
1
1
  # Classes
2
2
  module Nostr
3
3
  class KeyPair
4
- attr_reader private_key: String
5
- attr_reader public_key: String
4
+ attr_reader private_key: PrivateKey
5
+ attr_reader public_key: PublicKey
6
6
 
7
- def initialize: (private_key: String, public_key: String) -> void
7
+ def initialize: (private_key: PrivateKey, public_key: PublicKey) -> void
8
+
9
+ private
10
+
11
+ def validate_keys: (PrivateKey, PublicKey) -> void
8
12
  end
9
13
  end
data/sig/nostr/keygen.rbs CHANGED
@@ -3,11 +3,14 @@ module Nostr
3
3
  class Keygen
4
4
  def initialize: -> void
5
5
  def generate_key_pair: -> KeyPair
6
- def generate_private_key: -> String
7
- def extract_public_key: (String private_key) -> String
6
+ def generate_private_key: -> PrivateKey
7
+ def extract_public_key: (PrivateKey private_key) -> PublicKey
8
+ def get_key_pair_from_private_key: (PrivateKey private_key) -> KeyPair
8
9
 
9
10
  private
10
11
 
11
12
  attr_reader group: untyped
13
+
14
+ def validate_private_key: (PrivateKey private_key) -> void
12
15
  end
13
16
  end
@@ -0,0 +1,4 @@
1
+ module Nostr
2
+ class PrivateKey < Key
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module Nostr
2
+ class PublicKey < Key
3
+ end
4
+ end
@@ -0,0 +1,8 @@
1
+ module Nostr
2
+ module RelayMessageType
3
+ EOSE: String
4
+ EVENT: String
5
+ NOTICE: String
6
+ OK: String
7
+ end
8
+ end
data/sig/nostr/user.rbs CHANGED
@@ -5,14 +5,10 @@ module Nostr
5
5
 
6
6
  def initialize: (?keypair: KeyPair | nil, ?keygen: Keygen) -> void
7
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
- }
8
+ kind: Integer,
9
+ content: String,
10
+ ?created_at: Integer,
11
+ ?tags: Array[Array[String]],
16
12
  ) -> Event
17
13
 
18
14
  private
@@ -0,0 +1,41 @@
1
+ # Added only to satisfy the Steep requirements. Not 100% reliable.
2
+ module Bech32
3
+ module Nostr
4
+ class BareEntity
5
+ attr_reader hrp: untyped
6
+ attr_reader data: untyped
7
+
8
+ def initialize: (untyped hrp, untyped data) -> void
9
+ def encode: -> untyped
10
+ end
11
+
12
+ class TLVEntry
13
+ attr_reader type: (Float | Integer | String)?
14
+ attr_reader label: String?
15
+ attr_reader value: (Float | Integer | String)?
16
+
17
+ def initialize: ((Float | Integer | String)? `type`, (Float | Integer | String)? value, ?String? label) -> void
18
+ def to_payload: -> String
19
+ def to_s: -> String
20
+
21
+ private
22
+
23
+ def hex_string?: ((Float | Integer | String)? str) -> bool
24
+ end
25
+
26
+ class TLVEntity
27
+ TYPE_SPECIAL: Integer
28
+ TYPE_RELAY: Integer
29
+ TYPE_AUTHOR: Integer
30
+ TYPE_KIND: Integer
31
+ TYPES: [Integer, Integer, Integer, Integer]
32
+
33
+ attr_reader hrp: untyped
34
+ attr_reader entries: Array[TLVEntry]
35
+
36
+ def initialize: (untyped hrp, Array[TLVEntry] entries) -> void
37
+ def self.parse: (untyped hrp, untyped data) -> TLVEntity
38
+ def encode: -> untyped
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,20 @@
1
+ # Added only to satisfy the Steep requirements. Not 100% reliable.
2
+ module Bech32
3
+ module Nostr
4
+ module NIP19
5
+ HRP_PUBKEY: String
6
+ HRP_PRIVATE_KEY: String
7
+ HRP_NOTE_ID: String
8
+ HRP_PROFILE: String
9
+ HRP_EVENT: String
10
+ HRP_RELAY: String
11
+ HRP_EVENT_COORDINATE: String
12
+ BARE_PREFIXES: [String, String, String]
13
+ TLV_PREFIXES: [String, String, String, String]
14
+ ALL_PREFIXES: Array[String]
15
+
16
+ def decode: (untyped string) -> untyped
17
+ def self.decode: (untyped string) -> untyped
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,21 @@
1
+ # Added only to satisfy the Steep requirements. Not 100% reliable.
2
+ module Bech32
3
+ class SegwitAddr
4
+ HRP_MAINNET: String
5
+ HRP_TESTNET: String
6
+ HRP_REGTEST: String
7
+
8
+ attr_accessor hrp: String
9
+ attr_accessor ver: (Float | Integer | String)?
10
+ attr_accessor prog: Array[(Float | Integer | String)?]
11
+
12
+ def initialize: (?nil addr) -> void
13
+ def to_script_pubkey: -> ((Float | Integer | String)?)
14
+ def script_pubkey=: (untyped script_pubkey) -> (Array[(Float | Integer | String)?])
15
+ def addr: -> untyped
16
+
17
+ private
18
+
19
+ def parse_addr: (untyped addr) -> nil
20
+ end
21
+ end