async def _confirm_word(ctx, share_index, share_words, offset, count, group_index=None): # remove duplicates non_duplicates = list(set(share_words)) # shuffle list random.shuffle(non_duplicates) # take top NUM_OF_CHOICES words choices = non_duplicates[: MnemonicWordSelect.NUM_OF_CHOICES] # select first of them checked_word = choices[0] # find its index checked_index = share_words.index(checked_word) + offset # shuffle again so the confirmed word is not always the first choice random.shuffle(choices) if __debug__: debug.reset_word_index.publish(checked_index) # let the user pick a word select = MnemonicWordSelect(choices, share_index, checked_index, count, group_index) if __debug__: selected_word = await ctx.wait(select, debug.input_signal()) else: selected_word = await ctx.wait(select) # confirm it is the correct one return selected_word == checked_word
async def request_mnemonic( ctx: wire.GenericContext, word_count: int, backup_type: Optional[EnumTypeBackupType] ) -> Optional[str]: await ctx.call(ButtonRequest(code=ButtonRequestType.MnemonicInput), ButtonAck) words = [] # type: List[str] for i in range(word_count): if backup_types.is_slip39_word_count(word_count): keyboard = Slip39Keyboard( "Type word %s of %s:" % (i + 1, word_count) ) # type: Union[Slip39Keyboard, Bip39Keyboard] else: keyboard = Bip39Keyboard("Type word %s of %s:" % (i + 1, word_count)) if __debug__: word = await ctx.wait(keyboard, input_signal()) else: word = await ctx.wait(keyboard) words.append(word) try: word_validity.check(backup_type, words) except word_validity.AlreadyAdded: await show_share_already_added(ctx) return None except word_validity.IdentifierMismatch: await show_identifier_mismatch(ctx) return None except word_validity.ThresholdReached: await show_group_threshold_reached(ctx) return None return " ".join(words)
async def request_passphrase_ack(ctx: wire.Context, on_device: bool) -> str: if not on_device: text = Text("Passphrase entry", ui.ICON_CONFIG) text.normal("Please, type passphrase", "on connected host.") await Popup(text) req = PassphraseRequest(on_device=on_device) ack = await ctx.call(req, PassphraseAck) if on_device: if ack.passphrase is not None: raise wire.ProcessError( "Passphrase provided when it should not be") keyboard = PassphraseKeyboard("Enter passphrase", _MAX_PASSPHRASE_LEN) if __debug__: passphrase = await ctx.wait(keyboard, input_signal()) else: passphrase = await ctx.wait(keyboard) if passphrase is CANCELLED: raise wire.ActionCancelled("Passphrase cancelled") else: if ack.passphrase is None: raise wire.ProcessError("Passphrase not provided") passphrase = ack.passphrase state = cache.get_state(prev_state=ack.state, passphrase=passphrase) req = PassphraseStateRequest(state=state) ack = await ctx.call(req, PassphraseStateAck) return passphrase
async def request_mnemonic( ctx: wire.Context, count: int, mnemonic_type: int, mnemonics: List[str] ) -> str: await ctx.call(ButtonRequest(code=ButtonRequestType.MnemonicInput), ButtonAck) words = [] for i in range(count): if mnemonic_type == mnemonic.TYPE_SLIP39: keyboard = Slip39Keyboard("Type word %s of %s:" % (i + 1, count)) else: keyboard = Bip39Keyboard("Type word %s of %s:" % (i + 1, count)) if __debug__: word = await ctx.wait(keyboard, input_signal()) else: word = await ctx.wait(keyboard) if mnemonic_type == mnemonic.TYPE_SLIP39 and mnemonics: # check if first 3 words of mnemonic match # we can check against the first one, others were checked already if i < 3: share_list = mnemonics[0].split(" ") if share_list[i] != word: raise IdentifierMismatchError() elif i == 3: for share in mnemonics: share_list = share.split(" ") # check if the fourth word is different from previous shares if share_list[i] == word: raise ShareAlreadyAddedError() words.append(word) return " ".join(words)
async def request_mnemonic( ctx: wire.Context, word_count: int, backup_type: Optional[EnumTypeBackupType]) -> Optional[str]: await ctx.call(ButtonRequest(code=ButtonRequestType.MnemonicInput), ButtonAck) words = [] for i in range(word_count): if backup_types.is_slip39_word_count(word_count): keyboard = Slip39Keyboard("Type word %s of %s:" % (i + 1, word_count)) else: keyboard = Bip39Keyboard("Type word %s of %s:" % (i + 1, word_count)) if __debug__: word = await ctx.wait(keyboard, input_signal()) else: word = await ctx.wait(keyboard) if not await check_word_validity(ctx, i, word, backup_type, words): return None words.append(word) return " ".join(words)
async def _confirm_word(ctx, share_index, numbered_share_words, count): # TODO: duplicated words in the choice list # shuffle the numbered seed half, slice off the choices we need random.shuffle(numbered_share_words) numbered_choices = numbered_share_words[: MnemonicWordSelect.NUM_OF_CHOICES] # we always confirm the first (random) word index checked_index, checked_word = numbered_choices[0] if __debug__: debug.reset_word_index.publish(checked_index) # shuffle again so the confirmed word is not always the first choice random.shuffle(numbered_choices) # let the user pick a word choices = [word for _, word in numbered_choices] select = MnemonicWordSelect(choices, share_index, checked_index, count) if __debug__: selected_word = await ctx.wait(select, debug.input_signal()) else: selected_word = await ctx.wait(select) # confirm it is the correct one return selected_word == checked_word
def create_tasks(self) -> tuple[loop.AwaitableTask, ...]: from apps.debug import confirm_signal, input_signal return ( self.handle_timers(), self.handle_input_and_rendering(), self.handle_swipe(), confirm_signal(), input_signal(), )
def create_tasks(self) -> tuple[loop.AwaitableTask, ...]: tasks: tuple[loop.Task, ...] = ( self.handle_input(), self.handle_rendering(), self.handle_paging(), ) if __debug__: from apps.debug import input_signal return tasks + (input_signal(), ) else: return tasks
def create_tasks(self) -> Tuple[loop.Task, ...]: tasks = ( self.handle_input(), self.handle_rendering(), self.handle_paging(), ) # type: Tuple[loop.Task, ...] if __debug__: from apps.debug import input_signal return tasks + (input_signal(), ) else: return tasks
async def _request_on_device(ctx: wire.Context) -> str: await ctx.call(ButtonRequest(code=ButtonRequestType.PassphraseEntry), ButtonAck) keyboard = PassphraseKeyboard("Enter passphrase", _MAX_PASSPHRASE_LEN) if __debug__: passphrase = await ctx.wait(keyboard, input_signal()) else: passphrase = await ctx.wait(keyboard) if passphrase is CANCELLED: raise wire.ActionCancelled("Passphrase entry cancelled") assert isinstance(passphrase, str) return passphrase
async def request_word_count(ctx: wire.Context, dry_run: bool) -> int: await ctx.call(ButtonRequest(code=ButtonRequestType.MnemonicWordCount), ButtonAck) if dry_run: text = Text("Seed check", ui.ICON_RECOVERY) else: text = Text("Recovery mode", ui.ICON_RECOVERY) text.normal("Number of words?") if __debug__: count = await ctx.wait(WordSelector(text), input_signal()) count = int(count) # if input_signal was triggered, count is a string else: count = await ctx.wait(WordSelector(text)) return count
async def request_pin( prompt: str = "Enter your PIN", attempts_remaining: int = None, allow_cancel: bool = True, ) -> str: if attempts_remaining is None: subprompt = None elif attempts_remaining == 1: subprompt = "This is your last attempt" else: subprompt = "%s attempts remaining" % attempts_remaining dialog = PinDialog(prompt, subprompt, allow_cancel) while True: if __debug__: result = await loop.race(dialog, input_signal()) else: result = await dialog if result is CANCELLED: raise PinCancelled return result
def create_tasks(self) -> tuple[loop.Task, ...]: from apps.debug import input_signal return super().create_tasks() + (input_signal(), )
def create_tasks(self) -> tuple[loop.Task, ...]: return super().create_tasks() + (debug.input_signal(), )