module NostrManager class FetchLatestEvent < NostrManagerService TIMEOUT = 20 def initialize(relays:, filter:, max_events: 2) @relays = relays @filter = filter @max_events = max_events end def call received_events = 0 events = [] begin Timeout.timeout(TIMEOUT) do @relays.each do |url| event = NostrManager::FetchEvent.call(filter: @filter, relay_url: url) if event.present? events << event if events.none? { |e| e["id"] == event["id"] } received_events += 1 end if received_events >= @max_events Rails.logger.debug "Found #{@max_events} events, ending the search" break end end events.min_by { |e| e["created_at"] } end rescue Timeout::Error if events.size == 1 Rails.logger.debug "[nostr] Timeout: only found 1 event within #{TIMEOUT} seconds for filter: #{@filter.inspect}" events.first else Rails.logger.debug "[nostr] Timeout: no events found within #{TIMEOUT} seconds for filter: #{@filter.inspect}" nil end end end end end