nostr 0.4.0 → 0.6.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 (105) hide show
  1. checksums.yaml +4 -4
  2. data/.adr-dir +1 -0
  3. data/.editorconfig +1 -1
  4. data/.rubocop.yml +24 -1
  5. data/.tool-versions +2 -1
  6. data/CHANGELOG.md +70 -1
  7. data/README.md +93 -228
  8. data/adr/0001-record-architecture-decisions.md +19 -0
  9. data/adr/0002-introduction-of-signature-class.md +27 -0
  10. data/docs/.gitignore +4 -0
  11. data/docs/.vitepress/config.mjs +114 -0
  12. data/docs/README.md +44 -0
  13. data/docs/api-examples.md +49 -0
  14. data/docs/bun.lockb +0 -0
  15. data/docs/common-use-cases/bech32-encoding-and-decoding-(NIP-19).md +190 -0
  16. data/docs/common-use-cases/signing-and-verifying-events.md +50 -0
  17. data/docs/common-use-cases/signing-and-verifying-messages.md +43 -0
  18. data/docs/core/client.md +108 -0
  19. data/docs/core/keys.md +136 -0
  20. data/docs/core/user.md +43 -0
  21. data/docs/events/contact-list.md +29 -0
  22. data/docs/events/encrypted-direct-message.md +28 -0
  23. data/docs/events/recommend-server.md +32 -0
  24. data/docs/events/set-metadata.md +20 -0
  25. data/docs/events/text-note.md +15 -0
  26. data/docs/events.md +11 -0
  27. data/docs/getting-started/installation.md +21 -0
  28. data/docs/getting-started/overview.md +171 -0
  29. data/docs/implemented-nips.md +9 -0
  30. data/docs/index.md +42 -0
  31. data/docs/markdown-examples.md +85 -0
  32. data/docs/package.json +12 -0
  33. data/docs/relays/connecting-to-a-relay.md +21 -0
  34. data/docs/relays/publishing-events.md +29 -0
  35. data/docs/relays/receiving-events.md +6 -0
  36. data/docs/subscriptions/creating-a-subscription.md +49 -0
  37. data/docs/subscriptions/deleting-a-subscription.md +10 -0
  38. data/docs/subscriptions/filtering-subscription-events.md +115 -0
  39. data/docs/subscriptions/updating-a-subscription.md +4 -0
  40. data/lib/nostr/bech32.rb +203 -0
  41. data/lib/nostr/client.rb +2 -1
  42. data/lib/nostr/crypto.rb +93 -13
  43. data/lib/nostr/errors/error.rb +7 -0
  44. data/lib/nostr/errors/invalid_hrp_error.rb +21 -0
  45. data/lib/nostr/errors/invalid_key_format_error.rb +20 -0
  46. data/lib/nostr/errors/invalid_key_length_error.rb +20 -0
  47. data/lib/nostr/errors/invalid_key_type_error.rb +18 -0
  48. data/lib/nostr/errors/invalid_signature_format_error.rb +18 -0
  49. data/lib/nostr/errors/invalid_signature_length_error.rb +18 -0
  50. data/lib/nostr/errors/invalid_signature_type_error.rb +16 -0
  51. data/lib/nostr/errors/key_validation_error.rb +6 -0
  52. data/lib/nostr/errors/signature_validation_error.rb +6 -0
  53. data/lib/nostr/errors.rb +12 -0
  54. data/lib/nostr/event.rb +40 -13
  55. data/lib/nostr/event_kind.rb +1 -0
  56. data/lib/nostr/events/encrypted_direct_message.rb +8 -7
  57. data/lib/nostr/filter.rb +14 -11
  58. data/lib/nostr/key.rb +100 -0
  59. data/lib/nostr/key_pair.rb +54 -6
  60. data/lib/nostr/keygen.rb +44 -5
  61. data/lib/nostr/private_key.rb +36 -0
  62. data/lib/nostr/public_key.rb +36 -0
  63. data/lib/nostr/relay_message_type.rb +18 -0
  64. data/lib/nostr/signature.rb +67 -0
  65. data/lib/nostr/subscription.rb +2 -2
  66. data/lib/nostr/user.rb +17 -8
  67. data/lib/nostr/version.rb +1 -1
  68. data/lib/nostr.rb +7 -0
  69. data/nostr.gemspec +13 -13
  70. data/sig/nostr/bech32.rbs +14 -0
  71. data/sig/nostr/client.rbs +5 -5
  72. data/sig/nostr/crypto.rbs +8 -5
  73. data/sig/nostr/errors/error.rbs +4 -0
  74. data/sig/nostr/errors/invalid_hrb_error.rbs +6 -0
  75. data/sig/nostr/errors/invalid_key_format_error.rbs +5 -0
  76. data/sig/nostr/errors/invalid_key_length_error.rbs +5 -0
  77. data/sig/nostr/errors/invalid_key_type_error.rbs +5 -0
  78. data/sig/nostr/errors/invalid_signature_format_error.rbs +5 -0
  79. data/sig/nostr/errors/invalid_signature_length_error.rbs +5 -0
  80. data/sig/nostr/errors/invalid_signature_type_error.rbs +5 -0
  81. data/sig/nostr/errors/key_validation_error.rbs +4 -0
  82. data/sig/nostr/errors/signature_validation_error.rbs +4 -0
  83. data/sig/nostr/event.rbs +11 -10
  84. data/sig/nostr/events/encrypted_direct_message.rbs +2 -2
  85. data/sig/nostr/filter.rbs +3 -12
  86. data/sig/nostr/key.rbs +16 -0
  87. data/sig/nostr/key_pair.rbs +8 -3
  88. data/sig/nostr/keygen.rbs +5 -2
  89. data/sig/nostr/private_key.rbs +4 -0
  90. data/sig/nostr/public_key.rbs +4 -0
  91. data/sig/nostr/relay_message_type.rbs +8 -0
  92. data/sig/nostr/signature.rbs +14 -0
  93. data/sig/nostr/user.rbs +4 -8
  94. data/sig/vendor/bech32/nostr/entity.rbs +41 -0
  95. data/sig/vendor/bech32/nostr/nip19.rbs +20 -0
  96. data/sig/vendor/bech32/segwit_addr.rbs +21 -0
  97. data/sig/vendor/bech32.rbs +25 -0
  98. data/sig/vendor/event_emitter.rbs +10 -3
  99. data/sig/vendor/event_machine/channel.rbs +1 -1
  100. data/sig/vendor/faye/websocket/api.rbs +45 -0
  101. data/sig/vendor/faye/websocket/client.rbs +43 -0
  102. data/sig/vendor/faye/websocket.rbs +30 -0
  103. data/sig/vendor/schnorr/signature.rbs +16 -0
  104. data/sig/vendor/schnorr.rbs +3 -1
  105. metadata +102 -28
@@ -0,0 +1,67 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Nostr
4
+ # 64-bytes lowercase hex of the signature of the sha256 hash of the serialized event data,
5
+ # which is the same as the "id" field
6
+ class Signature < String
7
+ # The regular expression for hexadecimal lowercase characters
8
+ #
9
+ # @return [Regexp] The regular expression for hexadecimal lowercase characters
10
+ #
11
+ FORMAT = /^[a-f0-9]+$/
12
+
13
+ # The length of the signature in hex format
14
+ #
15
+ # @return [Integer] The length of the signature in hex format
16
+ #
17
+ LENGTH = 128
18
+
19
+ # Instantiates a new Signature
20
+ #
21
+ # @api public
22
+ #
23
+ # @example Instantiating a new signature
24
+ # Nostr::Signature.new(
25
+ # 'f418c97b50cc68227e82f4f3a79d79eb2b7a0fa517859c86e1a8fa91e3741b7f' \
26
+ # '06e070c44129227b83fcbe93cecb02a346804a4080ce47685ecad60ab4f5f128'
27
+ # )
28
+ #
29
+ # @param [String] hex_value Hex-encoded value of the signature
30
+ #
31
+ # @raise [SignatureValidationError]
32
+ #
33
+ def initialize(hex_value)
34
+ validate(hex_value)
35
+
36
+ super(hex_value)
37
+ end
38
+
39
+ private
40
+
41
+ # Hex-encoded value of the signature
42
+ #
43
+ # @api private
44
+ #
45
+ # @return [String] hex_value Hex-encoded value of the signature
46
+ #
47
+ attr_reader :hex_value
48
+
49
+ # Validates the hex value of the signature
50
+ #
51
+ # @api private
52
+ #
53
+ # @param [String] hex_value The signature in hex format
54
+ #
55
+ # @raise InvalidSignatureTypeError when the signature is not a string
56
+ # @raise InvalidSignatureLengthError when the signature's length is not 128 characters
57
+ # @raise InvalidSignatureFormatError when the signature is in an invalid format
58
+ #
59
+ # @return [void]
60
+ #
61
+ def validate(hex_value)
62
+ raise InvalidSignatureTypeError unless hex_value.is_a?(String)
63
+ raise InvalidSignatureLengthError unless hex_value.size == LENGTH
64
+ raise InvalidSignatureFormatError unless hex_value.match(FORMAT)
65
+ end
66
+ end
67
+ 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.6.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,17 @@ 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'
15
+ require_relative 'nostr/signature'
12
16
  require_relative 'nostr/event'
13
17
  require_relative 'nostr/events/encrypted_direct_message'
14
18
  require_relative 'nostr/client'
15
19
  require_relative 'nostr/user'
20
+ require_relative 'nostr/key'
21
+ require_relative 'nostr/private_key'
22
+ require_relative 'nostr/public_key'
16
23
 
17
24
  # Encapsulates all the gem's logic
18
25
  module Nostr
data/nostr.gemspec CHANGED
@@ -10,9 +10,9 @@ 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
- spec.required_ruby_version = '>= 3.2.0'
15
+ spec.required_ruby_version = '>= 3.3.0'
16
16
  spec.metadata['rubygems_mfa_required'] = 'true'
17
17
 
18
18
  spec.metadata['homepage_uri'] = spec.homepage
@@ -31,33 +31,33 @@ 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.7'
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'
39
39
  spec.add_dependency 'json', '~> 2.6'
40
40
 
41
41
  spec.add_development_dependency 'bundler-audit', '~> 0.9'
42
- spec.add_development_dependency 'dotenv', '~> 2.8'
42
+ spec.add_development_dependency 'dotenv', '~> 3.1'
43
43
  spec.add_development_dependency 'guard', '~> 2.18'
44
44
  spec.add_development_dependency 'guard-bundler', '~> 3.0'
45
45
  spec.add_development_dependency 'guard-bundler-audit', '~> 0.1'
46
46
  spec.add_development_dependency 'guard-rspec', '~> 4.7'
47
47
  spec.add_development_dependency 'guard-rubocop', '~> 1.5'
48
- spec.add_development_dependency 'overcommit', '~> 0.59'
48
+ spec.add_development_dependency 'overcommit', '~> 0.63'
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'
54
- spec.add_development_dependency 'rspec', '~> 3.12'
55
- spec.add_development_dependency 'rubocop', '~> 1.42'
52
+ spec.add_development_dependency 'rake', '~> 13.1'
53
+ spec.add_development_dependency 'rbs', '~> 3.4'
54
+ spec.add_development_dependency 'rspec', '~> 3.13'
55
+ spec.add_development_dependency 'rubocop', '~> 1.62'
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.27'
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,19 @@
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
+ def sign_message: (String, PrivateKey) -> Signature
11
+ def valid_sig?: (String, PublicKey, Signature) -> bool
12
+ def check_sig!: (String, PublicKey, Signature) -> bool
10
13
 
11
14
  private
12
15
 
13
- def compute_shared_key: (String, String) -> String
16
+ def compute_shared_key: (PrivateKey, PublicKey) -> String
14
17
  def hash_event:(Event) -> String
15
18
  end
16
19
  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,5 @@
1
+ module Nostr
2
+ class InvalidSignatureFormatError < SignatureValidationError
3
+ def initialize: -> void
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ module Nostr
2
+ class InvalidSignatureLengthError < SignatureValidationError
3
+ def initialize: -> void
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ module Nostr
2
+ class InvalidSignatureTypeError < SignatureValidationError
3
+ def initialize: -> void
4
+ end
5
+ end
@@ -0,0 +1,4 @@
1
+ module Nostr
2
+ class KeyValidationError < Error
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module Nostr
2
+ class SignatureValidationError < Error
3
+ end
4
+ end
data/sig/nostr/event.rbs CHANGED
@@ -1,39 +1,40 @@
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]]
7
7
  attr_reader content: String
8
- attr_accessor id: String?|nil
9
- attr_accessor sig: String?|nil
8
+ attr_accessor id: String?
9
+ attr_accessor sig: Signature?
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,
16
16
  ?tags: Array[Array[String]],
17
- ?id: String|nil,
18
- ?sig: String|nil
17
+ ?id: String?,
18
+ ?sig: Signature?
19
19
  ) -> void
20
20
 
21
21
  def serialize: -> [Integer, String, Integer, Integer, Array[Array[String]], String]
22
22
 
23
23
  def to_h: -> {
24
- id: String?|nil,
24
+ id: String?,
25
25
  pubkey: String,
26
26
  created_at: Integer,
27
27
  kind: Integer,
28
28
  tags: Array[Array[String]],
29
29
  content: String,
30
- sig: String?|nil
30
+ sig: String?
31
31
  }
32
32
  def ==: (Event other) -> bool
33
33
 
34
- def sign:(String) -> Event
34
+ def sign:(PrivateKey) -> Event
35
+ def verify_signature: -> bool
35
36
 
36
37
  def add_event_reference: (String) -> Array[Array[String]]
37
- def add_pubkey_reference: (String) -> Array[Array[String]]
38
+ def add_pubkey_reference: (PublicKey) -> Array[Array[String]]
38
39
  end
39
40
  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,14 @@
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
+ def to_ary: -> [PrivateKey, PublicKey]
9
+
10
+ private
11
+
12
+ def validate_keys: (PrivateKey, PublicKey) -> void
8
13
  end
9
14
  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
@@ -0,0 +1,14 @@
1
+ module Nostr
2
+ class Signature < String
3
+ FORMAT: Regexp
4
+ LENGTH: int
5
+
6
+ def initialize: (String) -> void
7
+
8
+ private
9
+
10
+ attr_reader hex_value: String
11
+
12
+ def validate: (String) -> nil
13
+ end
14
+ 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
@@ -0,0 +1,25 @@
1
+ # Added only to satisfy the Steep requirements. Not 100% reliable.
2
+ module Bech32
3
+ SEPARATOR: String
4
+ BECH32M_CONST: Integer
5
+
6
+ def encode: (untyped hrp, untyped data, untyped spec) -> untyped
7
+ def self.encode: (untyped hrp, untyped data, untyped spec) -> untyped
8
+ def decode: (untyped bech, ?Integer max_length) -> [untyped, untyped, Integer]?
9
+ def self.decode: (untyped bech, ?Integer max_length) -> [untyped, untyped, Integer]?
10
+ def create_checksum: (untyped hrp, untyped data, untyped spec) -> Array[Integer]
11
+ def self.create_checksum: (untyped hrp, untyped data, untyped spec) -> Array[Integer]
12
+ def verify_checksum: (untyped hrp, untyped data) -> Integer?
13
+ def self.verify_checksum: (untyped hrp, untyped data) -> Integer?
14
+ def expand_hrp: (untyped hrp) -> untyped
15
+ def self.expand_hrp: (untyped hrp) -> untyped
16
+ def convert_bits: (untyped data, untyped from, untyped to, ?true padding) -> Array[Integer]?
17
+ def self.convert_bits: (untyped data, untyped from, untyped to, ?true padding) -> Array[Integer]?
18
+ def polymod: (untyped values) -> Integer
19
+ def self.polymod: (untyped values) -> Integer
20
+
21
+ module Encoding
22
+ BECH32: Integer
23
+ BECH32M: Integer
24
+ end
25
+ end