Fetch user relays, synchronously

This commit is contained in:
Râu Cao 2024-10-12 12:45:50 +02:00
parent 9e3652479b
commit a08a4746f7
Signed by: raucao
GPG Key ID: 37036C356E56CC51
3 changed files with 96 additions and 0 deletions

View File

@ -0,0 +1,33 @@
module NostrManager
class DiscoverUserRelays < NostrManagerService
def initialize(pubkey:)
@pubkey = pubkey
@relays = Setting.nostr_discovery_relays
# @relays = %w[
# wss://nostr.kosmos.org
# wss://purplepag.es
# wss://relay.nostr.band
# wss://njump.me
# ]
end
def call
nip65_events = []
user_relays = []
filter = Nostr::Filter.new(
authors: [@pubkey],
kinds: [10002],
limit: 1,
)
@relays.each do |url|
event = NostrManager::FetchLatestEvent.call(filter: filter, relay_url: url)
if event.present? && user_relays.detect { |r| r[:id] == event["id"] }.nil?
user_relays << { id: event["id"], created_at: event["created_at"] }
end
end
puts user_relays.inspect
end
end
end

View File

@ -0,0 +1,59 @@
module NostrManager
class FetchLatestEvent < NostrManagerService
TIMEOUT = 1
def initialize(filter:, relay_url:)
@filter = filter
@relay = new_relay(relay_url)
@client = Nostr::Client.new
end
def call
filter, client, relay = @filter, @client, @relay
latest_event = nil
mutex = Mutex.new
received_event = ConditionVariable.new
log_prefix = "[nostr][#{@relay.name}]"
thread = Thread.new do
client.on :connect do
client.subscribe(filter: filter)
end
client.on :error do |e|
Rails.logger.info "#{log_prefix} Error: #{e}"
Thread.current.exit
end
client.on :message do |m|
msg = JSON.parse(m) rescue nil
if msg && msg[0] == "EVENT" && msg[2]
puts "#{log_prefix} Event received: #{msg[2]["id"]}"
mutex.synchronize do
latest_event = msg[2]
received_event.signal
end
elsif msg && msg[0] == "EOSE"
Thread.current.exit
end
end
client.connect relay
end
begin
Timeout.timeout(TIMEOUT) do
mutex.synchronize do
received_event.wait(mutex) if latest_event.nil?
end
end
rescue Timeout::Error
puts "#{log_prefix} Timeout: No event received within #{TIMEOUT} seconds"
ensure
thread.exit
end
latest_event
end
end
end

View File

@ -19,4 +19,8 @@ class NostrManagerService < ApplicationService
def site_user def site_user
Nostr::User.new(keypair: site_keypair) Nostr::User.new(keypair: site_keypair)
end end
def new_relay(url)
Nostr::Relay.new(url: url, name: URI.parse(url).host)
end
end end