def __init__(self, title="Enter account number", current_val='0'): super().__init__() self.title = add_label(title, scr=self, y=PADDING, style="title") self.note = add_label("Current account number: %s" % current_val, scr=self, style="hint") self.note.align(self.title, lv.ALIGN.OUT_BOTTOM_MID, 0, 5) self.kb = lv.btnm(self) self.kb.set_map(self.NUMERIC_CHARSET) self.kb.set_width(HOR_RES) self.kb.set_height(VER_RES // 2) self.kb.align(self, lv.ALIGN.IN_BOTTOM_MID, 0, 0) lbl = add_label('', style="title", scr=self) lbl.set_y(PADDING + 150) lbl.set_width(40) lbl.set_x(PADDING) self.ta = lv.ta(self) self.ta.set_text("") self.ta.set_width(HOR_RES - 2 * PADDING - 40) self.ta.set_x(PADDING + 40) self.ta.set_y(PADDING + 150) self.ta.set_cursor_type(lv.CURSOR.HIDDEN) self.ta.set_one_line(True) self.kb.set_event_cb(self.cb)
def __init__( self, generator, wordlist, fixer, title="Your recovery phrase:", note="Write it down and never show it to anybody.", ): self.fixer = fixer self.wordlist = wordlist mnemonic = generator(12) super().__init__(mnemonic, title, note) self.table.align(self.title, lv.ALIGN.OUT_BOTTOM_MID, 0, 50) self.table.set_event_cb(self.on_word_click) # enable callbacks self.table.set_click(True) self.close_label.set_text(lv.SYMBOL.LEFT + " Back") self.done_button = add_button(scr=self, callback=on_release(self.confirm)) self.done_label = lv.label(self.done_button) self.done_label.set_text(lv.SYMBOL.OK + " Done") align_button_pair(self.close_button, self.done_button) # toggle switch 12-24 words lbl = lv.label(self) lbl.set_text("Use 24 words") lbl.align(self.table, lv.ALIGN.OUT_BOTTOM_MID, 0, 40) lbl.set_x(120) self.switch_lbl = lbl self.switch = lv.sw(self) self.switch.off(lv.ANIM.OFF) self.switch.align(lbl, lv.ALIGN.OUT_RIGHT_MID, 20, 0) def cb(): wordcount = 24 if self.switch.get_state() else 12 self.table.set_mnemonic(generator(wordcount)) self.switch.set_event_cb(on_release(cb)) # fix mnemonic components self.kb = lv.btnm(self) self.kb.set_map([ "1", "2", "4", "8", "16", "32", "\n", "64", "128", "256", "512", "1024", "" ]) self.kb.set_ctrl_map([lv.btnm.CTRL.TGL_ENABLE for i in range(11)]) self.kb.set_width(HOR_RES) self.kb.set_height(100) self.kb.align(self.table, lv.ALIGN.OUT_BOTTOM_MID, 0, 5) self.kb.set_hidden(True) self.instruction = add_label( "Hint: click on any word above to edit it.", scr=self, style="hint") self.instruction.align(self.kb, lv.ALIGN.OUT_BOTTOM_MID, 0, 15)
def __init__(self, title="Enter your PIN code", note=None, get_word=None, subtitle=None): super().__init__() self.title = add_label(title, scr=self, y=PADDING, style="title") if subtitle is not None: lbl = add_label(subtitle, scr=self, style="hint") lbl.set_recolor(True) lbl.align(self.title, lv.ALIGN.OUT_BOTTOM_MID, 0, 10) if note is not None: lbl = add_label(note, scr=self, style="hint") lbl.align(self.title, lv.ALIGN.OUT_BOTTOM_MID, 0, 180) self.get_word = get_word if get_word is not None: self.words = add_label(get_word(b""), scr=self) self.words.align(self.title, lv.ALIGN.OUT_BOTTOM_MID, 0, 210) btnm = lv.btnm(self) # shuffle numbers to make sure # no constant fingerprints left on screen buttons = ["%d" % i for i in range(0, 10)] btnmap = [] for j in range(3): for i in range(3): v = rng.get_random_bytes(1)[0] % len(buttons) btnmap.append(buttons.pop(v)) btnmap.append("\n") btnmap = btnmap + [lv.SYMBOL.CLOSE, buttons.pop(), lv.SYMBOL.OK, ""] btnm.set_map(btnmap) btnm.set_width(HOR_RES) btnm.set_height(HOR_RES) btnm.align(self, lv.ALIGN.IN_BOTTOM_MID, 0, 0) # increase font size style = lv.style_t() lv.style_copy(style, btnm.get_style(lv.btnm.STYLE.BTN_REL)) style.text.font = lv.font_roboto_28 # remove feedback on press to avoid sidechannels btnm.set_style(lv.btnm.STYLE.BTN_REL, style) btnm.set_style(lv.btnm.STYLE.BTN_PR, style) self.pin = lv.ta(self) self.pin.set_text("") self.pin.set_pwd_mode(True) style = lv.style_t() lv.style_copy(style, styles["theme"].style.ta.oneline) style.text.font = lv.font_roboto_28 style.text.color = styles["theme"].style.scr.text.color style.text.letter_space = 15 self.pin.set_style(lv.label.STYLE.MAIN, style) self.pin.set_width(HOR_RES - 2 * PADDING) self.pin.set_x(PADDING) self.pin.set_y(PADDING + 50) self.pin.set_cursor_type(lv.CURSOR.HIDDEN) self.pin.set_one_line(True) self.pin.set_text_align(lv.label.ALIGN.CENTER) self.pin.set_pwd_show_time(0) self.pin.align(btnm, lv.ALIGN.OUT_TOP_MID, 0, -150) btnm.set_event_cb(feed_rng(self.cb))
def ask_for_password(cb_continue, title="Enter your password (optional)"): scr = switch_to_new_screen() add_label(title, style="title") btnm = lv.btnm(scr) btnm.set_map(CHARSET) btnm.set_width(HOR_RES) btnm.set_height(VER_RES // 3) btnm.align(scr, lv.ALIGN.IN_BOTTOM_MID, 0, 0) ta = lv.ta(scr) ta.set_text("") # ta.set_pwd_mode(True) ta.set_width(HOR_RES - 2 * PADDING) ta.set_x(PADDING) ta.set_text_align(lv.label.ALIGN.CENTER) ta.set_y(PADDING + 150) ta.set_cursor_type(lv.CURSOR.HIDDEN) ta.set_one_line(True) # ta.set_pwd_show_time(0) def cb(obj, event): if event == lv.EVENT.RELEASED: c = obj.get_active_btn_text() if c is None: return if c[0] == lv.SYMBOL.LEFT: ta.del_char() elif c == lv.SYMBOL.UP or c == lv.SYMBOL.DOWN: for i, ch in enumerate(CHARSET): if ch.isalpha(): if c == lv.SYMBOL.UP: CHARSET[i] = CHARSET[i].upper() else: CHARSET[i] = CHARSET[i].lower() elif ch == lv.SYMBOL.UP: CHARSET[i] = lv.SYMBOL.DOWN elif ch == lv.SYMBOL.DOWN: CHARSET[i] = lv.SYMBOL.UP btnm.set_map(CHARSET) elif c == "#@": btnm.set_map(CHARSET_EXTRA) elif c == "aA": btnm.set_map(CHARSET) elif c[0] == lv.SYMBOL.CLOSE: ta.set_text("") elif c[0] == lv.SYMBOL.OK: cb_continue(ta.get_text()) ta.set_text("") else: ta.add_text(c) btnm.set_event_cb(cb)
def ask_for_derivation(cb_continue, cb_back, title="Enter desired derivation path"): scr = switch_to_new_screen() add_label(title, style="title") btnm = lv.btnm(scr) btnm.set_map(PATH_CHARSET) btnm.set_width(HOR_RES) btnm.set_height(VER_RES // 2) btnm.align(scr, lv.ALIGN.IN_BOTTOM_MID, 0, 0) lbl = add_label("m/", style="title") lbl.set_y(PADDING + 150) lbl.set_width(40) lbl.set_x(PADDING) ta = lv.ta(scr) ta.set_text("") ta.set_width(HOR_RES - 2 * PADDING - 40) ta.set_x(PADDING + 40) ta.set_y(PADDING + 150) ta.set_cursor_type(lv.CURSOR.HIDDEN) ta.set_one_line(True) @feed_rng def cb(obj, event): if event == lv.EVENT.RELEASED: c = obj.get_active_btn_text() if c is None: return if c == "Back": cb_back() ta.set_text("") if c[0] == lv.SYMBOL.LEFT: ta.del_char() elif c[0] == lv.SYMBOL.CLOSE: ta.set_text("") elif c[0] == lv.SYMBOL.OK: cb_continue("m/" + ta.get_text()) ta.set_text("") elif c[0] == "h": ta.add_text("h/") else: ta.add_text(c) btnm.set_event_cb(cb)
def __init__(self, checker=None, lookup=None, title="Enter your recovery phrase"): super().__init__("", title) self.table.align(self.title, lv.ALIGN.OUT_BOTTOM_MID, 0, 10) self.checker = checker self.lookup = lookup self.close_button.del_async() self.close_button = None if lookup is not None: self.autocomplete = lv.btnm(self) self.kb = HintKeyboard(self) self.kb.set_map([ "Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P", "\n", "A", "S", "D", "F", "G", "H", "J", "K", "L", "\n", "Z", "X", "C", "V", "B", "N", "M", lv.SYMBOL.LEFT, "\n", lv.SYMBOL.LEFT + " Back", "Next word", lv.SYMBOL.OK + " Done", "" ]) if lookup is not None: # Next word button inactive self.kb.set_btn_ctrl(28, lv.btnm.CTRL.INACTIVE) if checker is not None: # Done inactive self.kb.set_btn_ctrl(29, lv.btnm.CTRL.INACTIVE) self.kb.set_width(HOR_RES) self.kb.set_height(VER_RES // 3) self.kb.align(self, lv.ALIGN.IN_BOTTOM_MID, 0, 0) self.kb.set_event_cb(self.callback) if lookup is not None: self.autocomplete.set_width(HOR_RES) self.autocomplete.set_height(50) self.autocomplete.align(self.kb, lv.ALIGN.OUT_TOP_MID, 0, 0) words = lookup("", 4) + [""] self.autocomplete.set_map(words) self.autocomplete.set_event_cb(self.select_word)
def __init__(self, title="Enter derivation path"): super().__init__() self.title = add_label(title, scr=self, y=PADDING, style="title") self.kb = lv.btnm(self) self.kb.set_map(type(self).PATH_CHARSET) self.kb.set_width(HOR_RES) self.kb.set_height(VER_RES // 2) self.kb.align(self, lv.ALIGN.IN_BOTTOM_MID, 0, 0) lbl = add_label("m/", style="title", scr=self) lbl.set_y(PADDING + 150) lbl.set_width(40) lbl.set_x(PADDING) self.ta = lv.ta(self) self.ta.set_text("") self.ta.set_width(HOR_RES - 2 * PADDING - 40) self.ta.set_x(PADDING + 40) self.ta.set_y(PADDING + 150) self.ta.set_cursor_type(lv.CURSOR.HIDDEN) self.ta.set_one_line(True) self.kb.set_event_cb(self.cb)
def ask_pin(first_time_usage, callback): scr = switch_to_new_screen() first_time_title = "Choose a PIN code" title = "Enter your PIN code" if first_time_usage: title = first_time_title title_lbl = add_label(title, y=PADDING, style="title") btnm = lv.btnm(scr) # shuffle numbers to make sure # no constant fingerprints left on screen buttons = ["%d" % i for i in range(0,10)] btnmap = [] for j in range(3): for i in range(3): v = rng.get_random_bytes(1)[0] % len(buttons) btnmap.append(buttons.pop(v)) btnmap.append("\n") btnmap = btnmap+[lv.SYMBOL.CLOSE, buttons.pop(), lv.SYMBOL.OK, ""] btnm.set_map(btnmap) btnm.set_width(HOR_RES) btnm.set_height(HOR_RES) btnm.align(scr, lv.ALIGN.IN_BOTTOM_MID, 0, 0) # remove feedback on press to avoid sidechannels btnm.set_style(lv.btnm.STYLE.BTN_PR,btnm.get_style(lv.btnm.STYLE.BTN_REL)) pin_lbl = lv.ta(scr) pin_lbl.set_text("") pin_lbl.set_pwd_mode(True) style = lv.style_t() lv.style_copy(style, styles["theme"].style.ta.oneline) style.text.font = lv.font_roboto_28 style.text.color = lv.color_hex(0xffffff) style.text.letter_space = 15 pin_lbl.set_style(lv.label.STYLE.MAIN, style) pin_lbl.set_width(HOR_RES-2*PADDING) pin_lbl.set_x(PADDING) pin_lbl.set_y(PADDING+50) pin_lbl.set_cursor_type(lv.CURSOR.HIDDEN) pin_lbl.set_one_line(True) pin_lbl.set_text_align(lv.label.ALIGN.CENTER) pin_lbl.set_pwd_show_time(0) instruct_txt = "Device tamper check.\nThese words should remain #ffffff the same every time#:" instruct_label = add_label(instruct_txt, 180, style="hint") instruct_label.set_recolor(True) antiphish_label = add_label(antiphishing_word(""), 250) Pin.read_counter() @feed_rng def cb(obj, event): nonlocal first_time_usage if event == lv.EVENT.RELEASED: c = obj.get_active_btn_text() if c is None: return if c == lv.SYMBOL.CLOSE: pin_lbl.set_text("") antiphish_label.set_text(antiphishing_word("")) elif c == lv.SYMBOL.OK: # FIXME: check PIN len Key.generate_key(pin_lbl.get_text()); if first_time_usage: Secret.save_secret(alert); callback() else: Pin.counter -= 1 Pin.save_counter(alert) if Pin.is_pin_valid(): Pin.reset_counter(alert) callback() else: instruct_label.set_text("#f07070 Wrong pin: %d/%d #" % (Pin.counter, Pin.ATTEMPTS_MAX)) if Pin.counter <= 0: Factory_settings.restore(alert) Secret.generate_secret() alert("Security","Device has been factory reset!") first_time_usage = True title_lbl.set_text(first_time_title) instruct_label.set_text(instruct_txt) pin_lbl.set_text("") antiphish_label.set_text(antiphishing_word("")) else: instruct_label.set_text(instruct_txt) pin_lbl.add_text(c) word = antiphishing_word(pin_lbl.get_text()) antiphish_label.set_text(antiphish_label.get_text() + " " + word) btnm.set_event_cb(cb);
def ask_for_mnemonic(cb_continue, cb_back, check_mnemonic=None, words_lookup=None, title="Enter your recovery phrase"): scr = switch_to_new_screen() add_label(title, style="title") table = add_mnemonic_table("", y=70) btnm = lv.btnm(scr) btnm.set_map([ "Q","W","E","R","T","Y","U","I","O","P","\n", "A","S","D","F","G","H","J","K","L","\n", "Z","X","C","V","B","N","M",lv.SYMBOL.LEFT,"\n", lv.SYMBOL.LEFT+" Back","Next word",lv.SYMBOL.OK+" Done","" ]) if words_lookup is not None: # Next word button inactive btnm.set_btn_ctrl(28, lv.btnm.CTRL.INACTIVE) if check_mnemonic is not None: # Done inactive btnm.set_btn_ctrl(29, lv.btnm.CTRL.INACTIVE) btnm.set_width(HOR_RES) btnm.set_height(VER_RES//3) btnm.align(scr, lv.ALIGN.IN_BOTTOM_MID, 0, 0) key_hint = lv.btn(scr) key_hint.set_size(50,60) key_lbl = add_label(" ", style="title", scr=key_hint) key_hint.set_hidden(True) @feed_rng def cb(obj, event): global words if event == lv.EVENT.PRESSING: c = obj.get_active_btn_text() if c is None: return if len(c)>1: key_hint.set_hidden(True) return key_hint.set_hidden(False) key_lbl.set_text(c) point = lv.point_t() indev = lv.indev_get_act() lv.indev_get_point(indev, point) key_hint.set_pos(point.x-25, point.y-130) elif event == lv.EVENT.RELEASED: key_hint.set_hidden(True) c = obj.get_active_btn_text() if c is None: return num = obj.get_active_btn() # if inactive button is clicked - return if obj.get_btn_ctrl(num,lv.btnm.CTRL.INACTIVE): return if c == lv.SYMBOL.LEFT+" Back": cb_back() elif c == lv.SYMBOL.LEFT: if len(words[-1]) > 0: words[-1] = words[-1][:-1] elif len(words) > 0: words = words[:-1] table_set_mnemonic(table, " ".join(words)) elif c == "Next word": if words_lookup is not None and len(words[-1])>=2: candidates = words_lookup(words[-1]) if len(candidates) == 1: words[-1] = candidates[0] words.append("") table_set_mnemonic(table, " ".join(words)) elif c == lv.SYMBOL.OK+" Done": pass else: if len(words) == 0: words.append("") words[-1] = words[-1]+c.lower() table_set_mnemonic(table, " ".join(words)) mnemonic = None if words_lookup is not None: btnm.set_btn_ctrl(28, lv.btnm.CTRL.INACTIVE) if len(words) > 0 and len(words[-1])>=2: candidates = words_lookup(words[-1]) if len(candidates) == 1 or words[-1] in candidates: btnm.clear_btn_ctrl(28, lv.btnm.CTRL.INACTIVE) mnemonic = " ".join(words[:-1]) if len(candidates) == 1: mnemonic += " "+candidates[0] else: mnemonic += " "+words[-1] else: mnemonic = " ".join(words) else: mnemonic = " ".join(words) if mnemonic is None: return mnemonic = mnemonic.strip() if check_mnemonic is not None and mnemonic is not None: if check_mnemonic(mnemonic): btnm.clear_btn_ctrl(29, lv.btnm.CTRL.INACTIVE) else: btnm.set_btn_ctrl(29, lv.btnm.CTRL.INACTIVE) # if user was able to click this button then mnemonic is correct if c == lv.SYMBOL.OK+" Done": cb_continue(mnemonic) btnm.set_event_cb(cb);
lv.indev_drv_register (indev_drv) # ********************************** # Start your codes here. # ********************************** def event_handler(obj, event): if event == lv.EVENT.VALUE_CHANGED: txt = obj.get_active_btn_text() print("%s was pressed" % txt) btnm_map = ["1", "2", "3", "4", "5", "\n", "6", "7", "8", "9", "0", "\n", "Action1", "Action2", ""] btnm1 = lv.btnm(lv.scr_act()) btnm1.set_map(btnm_map) btnm1.set_btn_width(10, 2) # Make "Action1" twice as wide as "Action2" btnm1.align(None, lv.ALIGN.CENTER, 0, 0) btnm1.set_event_cb(event_handler) # ********************************** # End your codes here. # ********************************** def on_timer(timer): lv.tick_inc(5) timer = Timer(Timer.TIMER0, Timer.CHANNEL0, mode = Timer.MODE_PERIODIC, period = 5, unit = Timer.UNIT_MS, callback = on_timer, arg = None) while True :
def __init__( self, checker=None, lookup=None, fixer=None, title="Enter your recovery phrase" ): super().__init__("", title) self.table.align(self.title, lv.ALIGN.OUT_BOTTOM_MID, 0, 10) self.checker = checker self.lookup = lookup self.close_button.del_async() self.close_button = None if lookup is not None: self.autocomplete = lv.btnm(self) self.kb = HintKeyboard(self) self.kb.set_map( [ "Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P", "\n", "A", "S", "D", "F", "G", "H", "J", "K", "L", "\n", "Z", "X", "C", "V", "B", "N", "M", lv.SYMBOL.LEFT, "\n", lv.SYMBOL.LEFT + " Back", "Next word", lv.SYMBOL.OK + " Done", "", ] ) if lookup is not None: # Next word button inactive self.kb.set_btn_ctrl(self.BTN_NEXT, lv.btnm.CTRL.INACTIVE) if checker is not None: # Done inactive self.kb.set_btn_ctrl(self.BTN_DONE, lv.btnm.CTRL.INACTIVE) self.kb.set_width(HOR_RES) self.kb.set_height(260) self.kb.align(self, lv.ALIGN.IN_BOTTOM_MID, 0, 0) self.kb.set_event_cb(self.callback) self.fixer = fixer if fixer is not None: self.fix_button = add_button("fix", on_release(self.fix_cb), self) self.fix_button.set_size(55, 30) # position it out of the screen but on correct y self.fix_button.align(self.table, lv.ALIGN.OUT_BOTTOM_MID, -400, -38) if lookup is not None: self.autocomplete.set_width(HOR_RES) self.autocomplete.set_height(50) self.autocomplete.align(self.kb, lv.ALIGN.OUT_TOP_MID, 0, 0) words = lookup("", 4) + [""] self.autocomplete.set_map(words) self.autocomplete.set_event_cb(self.select_word)