Class: Nostr::Client
Instance Attribute Summary collapse
Instance Method Summary
collapse
#clear, #emit, #initialize_event_emitter, #off, #on, #replace
Constructor Details
#initialize(signer: nil, private_key: nil, relay: nil, context: Context.new(timeout: 5)) ⇒ Client
Returns a new instance of Client.
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
|
# File 'lib/client.rb', line 14
def initialize(signer: nil, private_key: nil, relay: nil, context: Context.new(timeout: 5))
initialize_event_emitter
if signer
@signer = signer
elsif private_key
@signer = Nostr::Signer.new(private_key: private_key)
end
@relay = relay
@context = context
@running = false
@expected_response_id = nil
@response_condition = ConditionVariable.new
@response_mutex = Mutex.new
@event_to_publish = nil
@subscriptions = {}
@outbound_channel = EventMachine::Channel.new
@inbound_channel = EventMachine::Channel.new
@inbound_channel.subscribe do |msg|
case msg[:type]
when :open
emit :connect, msg[:relay]
when :message
parsed_data = Nostr::MessageHandler.handle(msg[:data])
emit :message, parsed_data
emit :event, parsed_data if parsed_data.type == "EVENT"
emit :ok, parsed_data if parsed_data.type == "OK"
emit :eose, parsed_data if parsed_data.type == "EOSE"
emit :closed, parsed_data if parsed_data.type == "CLOSED"
emit :notice, parsed_data if parsed_data.type == "NOTICE"
when :error
emit :error, msg[:message]
when :close
emit :close, msg[:code], msg[:reason]
end
end
end
|
Instance Attribute Details
#relay ⇒ Object
Returns the value of attribute relay.
10
11
12
|
# File 'lib/client.rb', line 10
def relay
@relay
end
|
#signer ⇒ Object
Returns the value of attribute signer.
9
10
11
|
# File 'lib/client.rb', line 9
def signer
@signer
end
|
#subscriptions ⇒ Object
Returns the value of attribute subscriptions.
11
12
13
|
# File 'lib/client.rb', line 11
def subscriptions
@subscriptions
end
|
Instance Method Details
#close ⇒ Object
123
124
125
126
127
128
129
130
131
|
# File 'lib/client.rb', line 123
def close
@running = false
EM.next_tick do
@ws_client.close if @ws_client
EM.add_timer(0.1) do
EM.stop if EM.reactor_running?
end
end
end
|
#connect(context: @context) ⇒ Object
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
|
# File 'lib/client.rb', line 84
def connect(context: @context)
@thread = Thread.new do
EM.run do
@ws_client = Faye::WebSocket::Client.new(@relay)
@outbound_channel.subscribe { |msg| @ws_client.send(msg) && emit(:send, msg) }
@ws_client.on :open do
@running = true
@inbound_channel.push(type: :open, relay: @relay)
end
@ws_client.on :message do |event|
@inbound_channel.push(type: :message, data: event.data)
end
@ws_client.on :error do |event|
@inbound_channel.push(type: :error, message: event.message)
end
@ws_client.on :close do |event|
context.cancel
@inbound_channel.push(type: :close, code: event.code, reason: event.reason)
end
end
end
if context
context.wait { @running }
end
end
|
#decrypt(event) ⇒ Object
76
77
78
|
# File 'lib/client.rb', line 76
def decrypt(event)
signer.decrypt(event)
end
|
#generate_delegation_tag(to:, conditions:) ⇒ Object
80
81
82
|
# File 'lib/client.rb', line 80
def generate_delegation_tag(to:, conditions:)
signer.generate_delegation_tag(to, conditions)
end
|
#npub ⇒ Object
64
65
66
|
# File 'lib/client.rb', line 64
def npub
signer.npub
end
|
#nsec ⇒ Object
56
57
58
|
# File 'lib/client.rb', line 56
def nsec
signer.nsec
end
|
#private_key ⇒ Object
60
61
62
|
# File 'lib/client.rb', line 60
def private_key
signer.private_key
end
|
#public_key ⇒ Object
68
69
70
|
# File 'lib/client.rb', line 68
def public_key
signer.public_key
end
|
#publish(event) ⇒ Object
133
134
135
136
137
|
# File 'lib/client.rb', line 133
def publish(event)
return false unless running?
@outbound_channel.push(['EVENT', event.to_json].to_json)
return true
end
|
#publish_and_wait(event, context: @context, close_on_finish: false) ⇒ Object
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
|
# File 'lib/client.rb', line 139
def publish_and_wait(event, context: @context, close_on_finish: false)
return false unless running?
response = nil
@outbound_channel.push(['EVENT', event.to_json].to_json)
response_thread = Thread.new do
context.wait do
@response_mutex.synchronize do
@response_condition.wait(@response_mutex) end
end
end
@inbound_channel.subscribe do |message|
parsed_data = Nostr::MessageHandler.handle(message[:data])
if parsed_data.type == "OK" && parsed_data.event_id == event.id
response = parsed_data
@response_condition.signal
end
end
response_thread.join
close if close_on_finish
response
end
|
#running? ⇒ Boolean
119
120
121
|
# File 'lib/client.rb', line 119
def running?
@running
end
|
#sign(event) ⇒ Object
72
73
74
|
# File 'lib/client.rb', line 72
def sign(event)
signer.sign(event)
end
|
#subscribe(subscription_id: SecureRandom.hex, filter: Filter.new) ⇒ Object
167
168
169
170
171
172
|
# File 'lib/client.rb', line 167
def subscribe(subscription_id: SecureRandom.hex, filter: Filter.new)
@subscriptions[subscription_id] = filter
@outbound_channel.push(["REQ", subscription_id, filter.to_h].to_json)
@subscriptions[subscription_id]
subscription_id
end
|
#unsubscribe(subscription_id) ⇒ Object
174
175
176
177
|
# File 'lib/client.rb', line 174
def unsubscribe(subscription_id)
@subscriptions.delete(subscription_id)
@outbound_channel.push(["CLOSE", subscription_id].to_json)
end
|
#unsubscribe_all ⇒ Object
179
180
181
|
# File 'lib/client.rb', line 179
def unsubscribe_all
@subscriptions.each{|s| unsubscribe(s[0])}
end
|