Class: Trezor::Device
- Inherits:
-
Object
show all
- Includes:
- Utils
- Defined in:
- lib/trezor/device.rb
Constant Summary
collapse
- HOST =
'http://127.0.0.1:21325'
{ origin: 'https://python.trezor.io' }
- MUTEX =
Mutex.new
Class Method Summary
collapse
Instance Method Summary
collapse
Constructor Details
#initialize(device_info) ⇒ Device
Returns a new instance of Device.
15
16
17
18
19
20
|
# File 'lib/trezor/device.rb', line 15
def initialize(device_info)
@session_counter = 0
@device_info = device_info
@connection = HTTP.persistent(HOST)
@connection.default_options..merge!(HEADERS)
end
|
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(method_name, *args, &block) ⇒ Object
64
65
66
67
|
# File 'lib/trezor/device.rb', line 64
def method_missing(method_name, *args, &block)
return super unless respond_to?(method_name)
call(Protobuf[method_name].new(*args), &block)
end
|
Class Method Details
.enumerate ⇒ Object
102
103
104
105
106
|
# File 'lib/trezor/device.rb', line 102
def self.enumerate
JSON.parse(HTTP[HEADERS].post("#{HOST}/enumerate").to_s).map do |device_info|
new(device_info)
end
end
|
.prompter(&block) ⇒ Object
123
124
125
126
127
128
129
130
131
132
133
|
# File 'lib/trezor/device.rb', line 123
def self.prompter(&block)
return @default_prompter = lambda(&block) if block_given?
prompter do |prompt, echo|
STDOUT.print(prompt)
if echo
STDIN.gets
else
STDIN.noecho(&:gets)
end.chomp.tap { STDOUT.print("\n") }
end
end
|
.with_session ⇒ Object
109
110
111
112
113
114
115
116
117
118
119
120
121
|
# File 'lib/trezor/device.rb', line 109
def self.with_session
MUTEX.lock
device = enumerate.first
unless device
return
end
device.start_session
yield(device)
ensure
device.end_session if device
MUTEX.unlock
end
|
Instance Method Details
#acquire! ⇒ Object
32
33
34
35
36
37
|
# File 'lib/trezor/device.rb', line 32
def acquire!
response = @connection.post("/acquire/#{@device_info['path']}/null")
body = response.to_s
raise body unless response.status.ok?
@session = JSON.parse(body)['session']
end
|
#call(message) ⇒ Object
47
48
49
50
51
52
53
54
55
|
# File 'lib/trezor/device.rb', line 47
def call(message)
response = post(message)
handler = "callback_#{response.class.name.demodulize}"
unless respond_to?(handler)
return response
end
call(send(handler, response))
end
|
73
74
75
|
# File 'lib/trezor/device.rb', line 73
def callback_ButtonRequest(msg)
Protobuf::ButtonAck.new
end
|
#callback_PassphraseRequest(msg) ⇒ Object
77
78
79
80
81
|
# File 'lib/trezor/device.rb', line 77
def callback_PassphraseRequest(msg)
return Protobuf::PassphraseAck.new if msg.on_device
passphrase = ask('Enter passphrase:', false).unicode_normalize(:nfkd)
Protobuf::PassphraseAck.new(passphrase: passphrase)
end
|
#callback_PassphraseStateRequest(msg) ⇒ Object
#callback_PinMatrixRequest(msg) ⇒ Object
#end_session ⇒ Object
27
28
29
30
|
# File 'lib/trezor/device.rb', line 27
def end_session
@session_counter -= 1
release! if @session_counter == 0
end
|
#post(message) ⇒ Object
57
58
59
60
61
62
|
# File 'lib/trezor/device.rb', line 57
def post(message)
serialized = Protobuf.serialize(message)
response = @connection.post("/call/#{@session}", body: serialized)
raise response.to_s unless response.status.ok?
Protobuf.decode(response.to_s)
end
|
#release! ⇒ Object
39
40
41
42
43
44
45
|
# File 'lib/trezor/device.rb', line 39
def release!
return unless @session
response = @connection.post("/release/#{@session}")
body = response.to_s
raise body unless response.status.ok?
@session = nil
end
|
#respond_to_missing?(method_name, include_private = false) ⇒ Boolean
69
70
71
|
# File 'lib/trezor/device.rb', line 69
def respond_to_missing?(method_name, include_private = false)
super || Protobuf[method_name].present?
end
|
#start_session ⇒ Object
22
23
24
25
|
# File 'lib/trezor/device.rb', line 22
def start_session
acquire! if @session_counter == 0
@session_counter += 1
end
|