Exemple #1
0
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
Exemple #2
0
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)
Exemple #3
0
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)
Exemple #5
0
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
Exemple #7
0
        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(),
            )
Exemple #8
0
    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
Exemple #9
0
    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
Exemple #12
0
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
Exemple #13
0
        def create_tasks(self) -> tuple[loop.Task, ...]:
            from apps.debug import input_signal

            return super().create_tasks() + (input_signal(), )
Exemple #14
0
 def create_tasks(self) -> tuple[loop.Task, ...]:
     return super().create_tasks() + (debug.input_signal(), )