nostr-ruby icon indicating copy to clipboard operation
nostr-ruby copied to clipboard

Assign multiples relays to `Nostr::Client` instance

Open TrumanBlurbank opened this issue 2 months ago • 2 comments

What is the recommended way to publish a Nostr::Event to multiples relays ? Currently, it seems that Nostr::Client takes only one relay option which force to recreate the client for each relays in a loop as there is no possibility to set it later on the client instance.

Proposed enhancements:

  1. Allows an array of relays in Nostr::Client that would automatically connect and publish to each relays

    c = Nostr::Client.new(
     private_key: "XXX",
     relays: ["wss://nos.lol", "wss://other.relay"] # Not possible ❌
    )
    
    e = Nostr::Event.new(...)
    e = c.sign(e)
    
    c.connect
    c.publish(e)
    c.close
    
  2. Allows to set the relay later to keep only one client instance and assign relay in a loop

    c = Nostr::Client.new(
      private_key: "XXX"
    )
    e = Nostr::Event.new(...)
    e = c.sign(e)
    
    ALL_RELAYS.each do |relay|
      c.relay = relay # Not possible ❌     
      c.connect
      c.publish(e)
      c.close
    end
    

Solution 1 would be very elegant, what do you think ? Thank you !

TrumanBlurbank avatar Nov 19 '25 09:11 TrumanBlurbank

Initializing more clients with the same signer should not waste too many resource, but a better approach would actually be preferable. I'm evaluating how to procede.

dtonon avatar Nov 20 '25 16:11 dtonon

Thank you.

What is your recommendation to publish to multiple relays until then ? A loop that instantiate a new client and event for each relay ? If so, how to ensure that the same event is referenced for each publising relay and not an independant event which will make the removal request manual for each one ? Would that be enough to use the same "d" tag in the loop ?

For example:

ALL_RELAYS = ['wss://relay1.test', 'wss://relay2.test', ...]

def call
  unique_identifier = 'my-unique-identifier-in-loop'
  published_at = Time.current.to_i.to_s

  ALL_RELAYS.each do |relay|
    @client = Nostr::Client.new(
      private_key: private_key,
      relay: relay
    )

    @event = Nostr::Event.new(
      kind: 30_023, # Long-form Content
      pubkey: @client.public_key,
      content: content,
      tags: [
        ['d', unique_identifier], # <== Here is the unique identifier used by each relay
        ['title', 'My title'],
        ['published_at', published_at]
      ]
    )

    @client.connect
    @event = @client.sign(@event)
    @response = @client.publish_and_wait(@event)
    @client.close
  end
end

TrumanBlurbank avatar Nov 20 '25 19:11 TrumanBlurbank