From 97037e6e30da86055b0d698332ccbed96602f7f2 Mon Sep 17 00:00:00 2001 From: Wilson Silva Date: Sat, 25 Feb 2023 12:40:19 +0700 Subject: [PATCH] Merge EventFragment into Event Treating Event as a Value Object in the strictest sense requires additional abstractions and internal complexity that the gem could do without, at least for now. --- .rubocop.yml | 3 + lib/nostr.rb | 1 - lib/nostr/event.rb | 110 ++++++++++++++++++++++++++--- lib/nostr/event_fragment.rb | 111 ------------------------------ sig/nostr/event.rbs | 23 ++++--- sig/nostr/event_fragment.rbs | 12 ---- spec/nostr/event_fragment_spec.rb | 90 ------------------------ 7 files changed, 117 insertions(+), 233 deletions(-) delete mode 100644 lib/nostr/event_fragment.rb delete mode 100644 sig/nostr/event_fragment.rbs delete mode 100644 spec/nostr/event_fragment_spec.rb diff --git a/.rubocop.yml b/.rubocop.yml index b36dbf4..1b5abbc 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -31,6 +31,9 @@ Metrics/BlockLength: - '**/*_spec.rb' - nostr.gemspec +Metrics/ParameterLists: + CountKeywordArgs: false + # ----------------------- RSpec ----------------------- RSpec/ExampleLength: diff --git a/lib/nostr.rb b/lib/nostr.rb index 325464a..ca6c4b0 100644 --- a/lib/nostr.rb +++ b/lib/nostr.rb @@ -8,7 +8,6 @@ require_relative 'nostr/subscription' require_relative 'nostr/relay' require_relative 'nostr/key_pair' require_relative 'nostr/event_kind' -require_relative 'nostr/event_fragment' require_relative 'nostr/event' require_relative 'nostr/client' require_relative 'nostr/user' diff --git a/lib/nostr/event.rb b/lib/nostr/event.rb index eb44fd6..3e41fb5 100644 --- a/lib/nostr/event.rb +++ b/lib/nostr/event.rb @@ -2,7 +2,65 @@ module Nostr # The only object type that exists in Nostr is an event. Events are immutable. - class Event < EventFragment + class Event + # 32-bytes hex-encoded public key of the event creator + # + # @api public + # + # @example + # event.pubkey # => '48df4af6e240ac5f7c5de89bf5941b249880be0e87d03685b178ccb1a315f52e' + # + # @return [String] + # + attr_reader :pubkey + + # Date of the creation of the vent. A UNIX timestamp, in seconds + # + # @api public + # + # @example + # event.created_at # => 1230981305 + # + # @return [Integer] + # + attr_reader :created_at + + # The kind of the event. An integer from 0 to 3 + # + # @api public + # + # @example + # event.kind # => 1 + # + # @return [Integer] + # + attr_reader :kind + + # An array of tags. Each tag is an array of strings + # + # @api public + # + # @example Tags referencing an event + # event.tags #=> [["e", "event_id", "relay URL"]] + # + # @example Tags referencing a key + # event.tags #=> [["p", "event_id", "relay URL"]] + # + # @return [Array] + # + attr_reader :tags + + # An arbitrary string + # + # @api public + # + # @example + # event.content # => 'Your feedback is appreciated, now pay $8' + # + # @return [String] + # + attr_reader :content + # 32-bytes sha256 of the the serialized event data. # To obtain the event.id, we sha256 the serialized event. The serialization is done over the UTF-8 JSON-serialized # string (with no white space or line breaks) @@ -12,7 +70,7 @@ module Nostr # @example Getting the event id # event.id # => 'ccf9fdf3e1466d7c20969c71ec98defcf5f54aee088513e1b73ccb7bd770d460' # - # @return [String] + # @return [String|nil] # attr_reader :id @@ -24,7 +82,7 @@ module Nostr # @example Getting the event signature # event.sig # => '' # - # @return [String] + # @return [String|nil] # attr_reader :sig @@ -44,16 +102,52 @@ module Nostr # 937c6d6e9855477638f5655c5d89c9aa5501ea9b578a66aced4f1cd7b3' # ) # - # - # @param id [String] 32-bytes sha256 of the the serialized event data. - # @param sig [String] 64-bytes signature of the sha256 hash of the serialized event data, which is + # @param id [String|nil] 32-bytes sha256 of the the serialized event data. + # @param sig [String|nil] 64-bytes signature of the sha256 hash of the serialized event data, which is # the same as the "id" field + # @param pubkey [String] 32-bytes hex-encoded public key of the event creator. + # @param created_at [Integer] Date of the creation of the vent. A UNIX timestamp, in seconds. + # @param kind [Integer] The kind of the event. An integer from 0 to 3. + # @param tags [Array] An array of tags. Each tag is an array of strings. + # @param content [String] Arbitrary string. # - def initialize(id:, sig:, **kwargs) - super(**kwargs) + def initialize( + pubkey:, + kind:, + content:, + created_at: Time.now.to_i, + tags: [], + id: nil, + sig: nil + ) @id = id @sig = sig + @pubkey = pubkey + @created_at = created_at + @kind = kind + @tags = tags + @content = content + end + + # Serializes the event, to obtain a SHA256 digest of it + # + # @api public + # + # @example Converting the event to a digest + # event.serialize + # + # @return [Array] The event as an array. + # + def serialize + [ + 0, + pubkey, + created_at, + kind, + tags, + content + ] end # Converts the event to a hash diff --git a/lib/nostr/event_fragment.rb b/lib/nostr/event_fragment.rb deleted file mode 100644 index b266123..0000000 --- a/lib/nostr/event_fragment.rb +++ /dev/null @@ -1,111 +0,0 @@ -# frozen_string_literal: true - -module Nostr - # Part of an +Event+. A complete +Event+ must have an +id+ and a +sig+. - class EventFragment - # 32-bytes hex-encoded public key of the event creator - # - # @api public - # - # @example - # event.pubkey # => '48df4af6e240ac5f7c5de89bf5941b249880be0e87d03685b178ccb1a315f52e' - # - # @return [String] - # - attr_reader :pubkey - - # Date of the creation of the vent. A UNIX timestamp, in seconds - # - # @api public - # - # @example - # event.created_at # => 1230981305 - # - # @return [Integer] - # - attr_reader :created_at - - # The kind of the event. An integer from 0 to 3 - # - # @api public - # - # @example - # event.kind # => 1 - # - # @return [Integer] - # - attr_reader :kind - - # An array of tags. Each tag is an array of strings - # - # @api public - # - # @example Tags referencing an event - # event.tags #=> [["e", "event_id", "relay URL"]] - # - # @example Tags referencing a key - # event.tags #=> [["p", "event_id", "relay URL"]] - # - # @return [Array] - # - attr_reader :tags - - # An arbitrary string - # - # @api public - # - # @example - # event.content # => 'Your feedback is appreciated, now pay $8' - # - # @return [String] - # - attr_reader :content - - # Instantiates a new EventFragment - # - # @api public - # - # @example - # Nostr::EventFragment.new( - # pubkey: 'ccf9fdf3e1466d7c20969c71ec98defcf5f54aee088513e1b73ccb7bd770d460', - # created_at: 1230981305, - # kind: 1, - # tags: [['e', '189df012cfff8a075785b884bd702025f4a7a37710f581c4ac9d33e24b585408']], - # content: 'Your feedback is appreciated, now pay $8' - # ) - # - # @param pubkey [String] 32-bytes hex-encoded public key of the event creator. - # @param created_at [Integer] Date of the creation of the vent. A UNIX timestamp, in seconds. - # @param kind [Integer] The kind of the event. An integer from 0 to 3. - # @param tags [Array] An array of tags. Each tag is an array of strings. - # @param content [String] Arbitrary string. - # - def initialize(pubkey:, kind:, content:, created_at: Time.now.to_i, tags: []) - @pubkey = pubkey - @created_at = created_at - @kind = kind - @tags = tags - @content = content - end - - # Serializes the event fragment, to obtain a SHA256 hash of it - # - # @api public - # - # @example Converting the event to a hash - # event_fragment.serialize - # - # @return [Array] The event fragment as an array. - # - def serialize - [ - 0, - pubkey, - created_at, - kind, - tags, - content - ] - end - end -end diff --git a/sig/nostr/event.rbs b/sig/nostr/event.rbs index b863df6..993e60e 100644 --- a/sig/nostr/event.rbs +++ b/sig/nostr/event.rbs @@ -1,23 +1,24 @@ module Nostr - class Event < EventFragment - attr_reader id: String - attr_reader sig: String + class Event + attr_reader pubkey: String + attr_reader created_at: Integer + attr_reader kind: Integer + attr_reader tags: Array[String] + attr_reader content: String + attr_reader id: String?|nil + attr_reader sig: String?|nil - def initialize: (id: String, sig: String, - created_at: Integer, - kind: Integer, - tags: Array[String], - content: String, - ) -> void + def initialize: (pubkey: String, kind: Integer, content: String, ?created_at: Integer, ?tags: Array[String], ?id: String|nil, ?sig: String|nil) -> void + def serialize: -> [Integer, String, Integer, Integer, Array[String], String] def to_h: -> { - id: String, + id: String?|nil, pubkey: String, created_at: Integer, kind: Integer, tags: Array[String], content: String, - sig: String + sig: String?|nil } def ==: (Event other) -> bool end diff --git a/sig/nostr/event_fragment.rbs b/sig/nostr/event_fragment.rbs deleted file mode 100644 index 1f377d8..0000000 --- a/sig/nostr/event_fragment.rbs +++ /dev/null @@ -1,12 +0,0 @@ -module Nostr - class EventFragment - attr_reader pubkey: String - attr_reader created_at: Integer - attr_reader kind: Integer - attr_reader tags: Array[String] - attr_reader content: String - - def initialize: (pubkey: String, kind: Integer, content: String, ?created_at: Integer, ?tags: Array[String]) -> void - def serialize: -> [Integer, String, Integer, Integer, Array[String], String] - end -end diff --git a/spec/nostr/event_fragment_spec.rb b/spec/nostr/event_fragment_spec.rb deleted file mode 100644 index 8f8b272..0000000 --- a/spec/nostr/event_fragment_spec.rb +++ /dev/null @@ -1,90 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -RSpec.describe Nostr::EventFragment do - let(:event_fragment) do - described_class.new( - pubkey: 'ccf9fdf3e1466d7c20969c71ec98defcf5f54aee088513e1b73ccb7bd770d460', - created_at: 1_230_981_305, - kind: 1, - tags: [ - %w[e 189df012cfff8a075785b884bd702025f4a7a37710f581c4ac9d33e24b585408], - %w[p 472f440f29ef996e92a186b8d320ff180c855903882e59d50de1b8bd5669301e] - ], - content: 'Your feedback is appreciated, now pay $8' - ) - end - - describe '.new' do - it 'creates an instance of an event fragment' do - event_fragment = described_class.new( - pubkey: 'ccf9fdf3e1466d7c20969c71ec98defcf5f54aee088513e1b73ccb7bd770d460', - created_at: 1_230_981_305, - kind: 1, - tags: [ - %w[e 189df012cfff8a075785b884bd702025f4a7a37710f581c4ac9d33e24b585408], - %w[p 472f440f29ef996e92a186b8d320ff180c855903882e59d50de1b8bd5669301e] - ], - content: 'Your feedback is appreciated, now pay $8' - ) - - expect(event_fragment).to be_an_instance_of(described_class) - end - end - - describe '#content' do - it 'exposes the event fragment content' do - expect(event_fragment.content).to eq('Your feedback is appreciated, now pay $8') - end - end - - describe '#created_at' do - it 'exposes the event fragment creation date' do - expect(event_fragment.created_at).to eq(1_230_981_305) - end - end - - describe '#kind' do - it 'exposes the event fragment kind' do - expect(event_fragment.kind).to eq(1) - end - end - - describe '#pubkey' do - it 'exposes the event fragment pubkey' do - expect(event_fragment.pubkey).to eq('ccf9fdf3e1466d7c20969c71ec98defcf5f54aee088513e1b73ccb7bd770d460') - end - end - - describe '#serialize' do - it 'serializes the event fragment according to NIP-01' do - serialized_event_fragment = event_fragment.serialize - - expect(serialized_event_fragment).to eq( - [ - 0, - 'ccf9fdf3e1466d7c20969c71ec98defcf5f54aee088513e1b73ccb7bd770d460', - 1_230_981_305, - 1, - [ - %w[e 189df012cfff8a075785b884bd702025f4a7a37710f581c4ac9d33e24b585408], - %w[p 472f440f29ef996e92a186b8d320ff180c855903882e59d50de1b8bd5669301e] - ], - 'Your feedback is appreciated, now pay $8' - ] - ) - end - end - - describe '#tags' do - it 'exposes the event fragment tags' do - expect(event_fragment.tags).to eq( - [ - %w[e 189df012cfff8a075785b884bd702025f4a7a37710f581c4ac9d33e24b585408], - %w[p 472f440f29ef996e92a186b8d320ff180c855903882e59d50de1b8bd5669301e] - ] - ) - end - end -end