Fetch user relays, synchronously
This commit is contained in:
parent
9e3652479b
commit
a08a4746f7
33
app/services/nostr_manager/discover_user_relays.rb
Normal file
33
app/services/nostr_manager/discover_user_relays.rb
Normal 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
|
59
app/services/nostr_manager/fetch_latest_event.rb
Normal file
59
app/services/nostr_manager/fetch_latest_event.rb
Normal 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
|
@ -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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user