Implemented Button* messages

pull/25/head
slush 12 years ago
parent 1409665302
commit e203d2ef53

@ -45,21 +45,26 @@ class BitkeyClient(object):
def _pprint(self, msg):
return "<%s>:\n%s" % (msg.__class__.__name__, msg)
def setup_debuglink(self, pin_correct=False, otp_correct=False):
def setup_debuglink(self, button=None, pin_correct=False, otp_correct=False):
self.debug_button = button
self.debug_pin = pin_correct
self.debug_otp = otp_correct
def call(self, msg, button=None, tries=1):
def call(self, msg):
if self.debug:
print '----------------------'
print "Sending", self._pprint(msg)
self.transport.write(msg)
if self.debuglink and button != None:
self.debuglink.press_button(button)
resp = self.transport.read_blocking()
resp = self.transport.read()
if isinstance(resp, proto.ButtonRequest):
if self.debuglink and self.debug_button:
print "Pressing button", self.debug_button
self.debuglink.press_button(self.debug_button)
self.transport.write(proto.ButtonAck())
resp = self.transport.read_blocking()
if isinstance(resp, proto.OtpRequest):
if self.debuglink:
@ -72,7 +77,7 @@ class BitkeyClient(object):
otp = self.input_func("OTP required: ", resp.message)
msg2 = proto.OtpAck(otp=otp)
return self.call(msg2, button, tries)
return self.call(msg2)
if isinstance(resp, proto.PinRequest):
if self.debuglink:
@ -85,27 +90,20 @@ class BitkeyClient(object):
pin = self.input_func("PIN required: ", resp.message)
msg2 = proto.PinAck(pin=pin)
return self.call(msg2, button, tries)
return self.call(msg2)
if isinstance(resp, proto.Failure):
self.message_func(resp.message)
if resp.code == 3:
if tries <= 1:
raise Exception("OTP is invalid, too many retries")
self.message_func("OTP is invalid, let's try again...")
raise Exception("OTP is invalid")
elif resp.code == 4:
raise Exception("Action cancelled by user")
elif resp.code == 6:
if tries <= 1:
raise Exception("PIN is invalid, too many retries")
self.message_func("PIN is invalid, let's try again...")
raise Exception("PIN is invalid")
return self.call(msg, button, tries-1)
if isinstance(resp, proto.Failure):
raise Exception(resp.code, resp.message)
if self.debug:
@ -122,6 +120,7 @@ class BitkeyClient(object):
outputs: list of TxOutput
'''
tx = proto.SignTx()
tx.algo = self.algo # Choose BIP32 or ELECTRUM way for deterministic keys
tx.random = os.urandom(256) # Provide additional entropy to the device
@ -159,6 +158,7 @@ class BitkeyClient(object):
return s_inputs
'''
def load_device(self, seed, otp, pin, spv, button=None):
self.call(proto.LoadDevice(seed=seed, otp=otp, pin=pin, spv=spv), button=button)
self.init_device()
def load_device(self, seed, otp, pin, spv):
resp = self.call(proto.LoadDevice(seed=seed, otp=otp, pin=pin, spv=spv))
self.init_device()
return isinstance(resp, proto.Success)

@ -1,10 +1,10 @@
import bitkey_pb2 as proto
def otp_info(otp):
print "Device asks for OTP %s" % otp
print "Device asks for OTP %s" % otp.otp
def pin_info(pin):
print "Device asks for PIN %s" % pin
print "Device asks for PIN %s" % pin.pin
def button_press(yes_no):
print "User pressed", '"y"' if yes_no else '"n"'
@ -12,31 +12,32 @@ def button_press(yes_no):
class DebugLink(object):
def __init__(self, transport, otp_func=otp_info, pin_func=pin_info, button_func=button_press):
self.transport = transport
self.otp_func = otp_func
self.pin_func = pin_func
self.button_func = button_func
def get_state(self, otp=False, pin=False):
self.transport.write(proto.DebugLinkGetState(otp=otp, pin=pin))
return self.transport.read_blocking()
def read_otp(self):
obj = self.transport.read()
if not isinstance(obj, proto.OtpAck):
raise Exception("Expected OtpAck object, got %s" % obj)
obj = self.get_state(otp=True).otp
print "Read OTP:", obj.otp
self.otp_func(obj)
return obj
def read_pin(self):
obj = self.transport.read()
if not isinstance(obj, proto.PinAck):
raise Exception("Expected PinAck object, got %s" % obj)
obj = self.get_state(pin=True).pin
print "Read PIN:", obj.pin
self.pin_func(obj)
return obj
def press_button(self, yes_no):
print "Pressing", yes_no
self.button_func(yes_no)
self.transport.write(proto.DebugLinkDecision(yes_no=yes_no))
#obj = self.transport.read()
#if not isinstance(obj, proto.Success):
# raise Exception("Expected Success object, got %s" % obj)
def press_yes(self):
self.press_button(True)

Loading…
Cancel
Save