from trezor import loop, res, ui from trezor.ui.confirm import CONFIRMED, ConfirmDialog from trezor.ui.pin import PinMatrix if __debug__: from apps.debug import input_signal class PinCancelled(Exception): pass @ui.layout async def request_pin(label=None, cancellable: bool = True) -> str: def onchange(): c = dialog.cancel if matrix.pin: back = res.load(ui.ICON_BACK) if c.content is not back: c.normal_style = ui.BTN_CLEAR["normal"] c.content = back c.enable() c.taint() else: lock = res.load(ui.ICON_LOCK) if not cancellable and c.content: c.content = "" c.disable() c.taint() elif c.content is not lock: c.normal_style = ui.BTN_CANCEL["normal"] c.content = lock c.enable() c.taint() c.render() if label is None: label = "Enter your PIN" matrix = PinMatrix(label) matrix.onchange = onchange dialog = ConfirmDialog(matrix) dialog.cancel.area = ui.grid(12) dialog.confirm.area = ui.grid(14) matrix.onchange() while True: if __debug__: result = await loop.spawn(dialog, input_signal) if isinstance(result, str): return result else: result = await dialog if result == CONFIRMED: return matrix.pin elif matrix.pin: # reset matrix.change("") continue else: # cancel raise PinCancelled()