Пример #1
0
 async def menu(self, show_screen):
     buttons = [
         (None, "Dice Roller"),
         (DICE_ROLL_DEFAULT, "Roll default (d6) dice"),
         (DICE_ROLL_D3, "Roll d3 dice"),
         (DICE_ROLL_D4, "Roll d4 dice"),
         (DICE_ROLL_D6, "Roll d6 dice"),
         (DICE_ROLL_D8, "Roll d8 dice"),
         (DICE_ROLL_D10, "Roll d10 dice"),
         (DICE_ROLL_D12, "Roll d12 dice"),
         (DICE_ROLL_D20, "Roll d20 dice"),
     ]
     menuitem = await show_screen(
         Menu(buttons,
              title="Which dice do you want to roll?",
              last=(255, None)))
     while menuitem != 255:
         if menuitem in [
                 DICE_ROLL_DEFAULT, DICE_ROLL_D3, DICE_ROLL_D4,
                 DICE_ROLL_D6, DICE_ROLL_D8, DICE_ROLL_D10, DICE_ROLL_D12,
                 DICE_ROLL_D20, DICE_ROLL_D100
         ]:
             roll = True
             while roll:
                 scr = DiceRollScreen(
                     title="Rolled dice ",
                     note="Choosen dice: d%s" % menuitem,
                     message="%s" % roll_dice(menuitem),
                 )
                 roll = await show_screen(scr)
             menuitem = await show_screen(Menu(buttons, last=(255, None)))
Пример #2
0
    async def storage_menu(self):
        """Manage storage"""
        buttons = [
            # id, text
            (None, "Key management"),
            (0, "Save key to flash"),
            (1, "Load key from flash"),
            (2, "Delete key from flash"),
        ]

        # we stay in this menu until back is pressed
        while True:
            # wait for menu selection
            menuitem = await self.show(Menu(buttons, last=(255, None)))
            # process the menu button:
            # back button
            if menuitem == 255:
                return
            elif menuitem == 0:
                await self.save_mnemonic()
                await self.show(
                    Alert("Success!",
                          "Your key is stored in flash now.",
                          button_text="OK"))
            elif menuitem == 1:
                await self.load_mnemonic()
                await self.show(
                    Alert("Success!", "Your key is loaded.", button_text="OK"))
            elif menuitem == 2:
                await self.delete_mnemonic()
                await self.show(
                    Alert("Success!",
                          "Your key is deleted from flash.",
                          button_text="OK"))
Пример #3
0
 async def menu(self, show_screen):
     buttons = [(None, "Your wallets")]
     buttons += [(w, w.name) for w in self.wallets if not w.is_watchonly]
     if len(buttons) != (len(self.wallets) + 1):
         buttons += [(None, "Watch only wallets")]
         buttons += [(w, w.name) for w in self.wallets if w.is_watchonly]
     menuitem = await show_screen(Menu(buttons, last=(255, None)))
     if menuitem == 255:
         # we are done
         return False
     else:
         w = menuitem
         # pass wallet and network
         self.show_loader(title="Loading wallet...")
         cmd = await w.show(self.network, show_screen)
         if cmd == DELETE:
             scr = Prompt(
                 "Delete wallet?",
                 'You are deleting wallet "%s".\n'
                 "Are you sure you want to do it?" % w.name,
             )
             conf = await show_screen(scr)
             if conf:
                 self.delete_wallet(w)
         elif cmd == EDIT:
             scr = InputScreen(title="Enter new wallet name",
                               note="",
                               suggestion=w.name)
             name = await show_screen(scr)
             if name is not None and name != w.name and name != "":
                 w.name = name
                 w.save(self.keystore)
         return True
Пример #4
0
 async def menu(self, show_screen):
     buttons = [(None, "Your wallets")]
     buttons += [(w, w.name) for w in self.wallets]
     menuitem = await show_screen(Menu(buttons, last=(255, None)))
     if menuitem == 255:
         # we are done
         return False
     else:
         w = menuitem
         # pass wallet and network
         scr = WalletScreen(w, self.network, idx=w.unused_recv)
         cmd = await show_screen(scr)
         if cmd == DELETE:
             scr = Prompt(
                 "Delete wallet?", "You are deleting wallet \"%s\".\n"
                 "Are you sure you want to do it?" % w.name)
             conf = await show_screen(scr)
             if conf:
                 self.delete_wallet(w)
         elif cmd == EDIT:
             scr = InputScreen(title="Enter new wallet name",
                               note="",
                               suggestion=w.name)
             name = await show_screen(scr)
             if name is not None and name != w.name and name != "":
                 w.name = name
                 w.save(self.keystore)
         return True
Пример #5
0
 async def show(self, network, show_screen):
     while True:
         scr = WalletScreen(self, network, idx=self.unused_recv)
         cmd = await show_screen(scr)
         if cmd == MENU:
             buttons = [
                 (INFO, "Show detailed information"),
                 (EDIT, lv.SYMBOL.EDIT + " Change the name"),
                 # value, label,                            enabled, color
                 (DELETE, lv.SYMBOL.TRASH + " Delete wallet", True, 0x951E2D
                  ),
             ]
             cmd = await show_screen(
                 Menu(buttons,
                      last=(255, None),
                      title=self.name,
                      note="What do you want to do?"))
             if cmd == 255:
                 continue
             elif cmd == INFO:
                 keys = self.get_key_dicts(network)
                 for k in keys:
                     k["mine"] = True if self.keystore and self.keystore.owns(
                         k["key"]) else False
                 await show_screen(
                     WalletInfoScreen(self.name, self.full_policy, keys,
                                      self.is_miniscript))
                 continue
         # other commands go to the wallet manager
         return cmd
Пример #6
0
    async def storage_menu(self):
        """Manage storage"""
        enabled = self.connection.isCardInserted()
        buttons = [
            # id, text
            (None, "Smartcard storage"),
            (0, "Save key to the card", enabled),
            (1, "Load key from the card", enabled),
            (2, "Delete key from the card", enabled),
            (3, "Use a different card", enabled)
        ]

        # we stay in this menu until back is pressed
        while True:
            note = "Card fingerprint: %s" % self.hexid
            # wait for menu selection
            menuitem = await self.show(
                Menu(buttons, note=note, last=(255, None)))
            # process the menu button:
            # back button
            if menuitem == 255:
                return
            elif menuitem == 0:
                await self.save_mnemonic()
                await self.show(
                    Alert(
                        "Success!",
                        "Your key is stored on the smartcard now.",
                        button_text="OK",
                    ))
            elif menuitem == 1:
                await self.load_mnemonic()
                await self.show(
                    Alert("Success!", "Your key is loaded.", button_text="OK"))
            elif menuitem == 2:
                await self.delete_mnemonic()
                await self.show(
                    Alert(
                        "Success!",
                        "Your key is deleted from the smartcard.",
                        button_text="OK",
                    ))
            elif menuitem == 3:
                if await self.show(
                        Prompt(
                            "Switching the smartcard",
                            "To use a different smartcard you need "
                            "to provide a PIN for current one first!\n\n"
                            "Continue?")):
                    self.lock()
                    await self.unlock()
                    self.lock()
                    self.applet.close_secure_channel()
                    await self.show(
                        Alert("Please swap the card",
                              "Now you can insert another card and set it up.",
                              button_text="Continue"))
                    await self.check_card(check_pin=True)
                    await self.unlock()
    async def menu(self, show_screen):
        buttons = [
            (None, "Dice Rolls (D6)"),
            (FLUSH_ROLLS,  "Create new seed"),
            (ADD_ROLL,  "Continue current seed"),
        ]

        menuitem = await show_screen(Menu(buttons, title="Seed creation by rolling dice", last=(255, None)))
        while menuitem != 255:
            if menuitem in PIPS or menuitem in [FLUSH_ROLLS, ADD_ROLL]:
                if menuitem == FLUSH_ROLLS:
                    self.rolls = []
                elif menuitem == ADD_ROLL:
                    pass # continue mix into current seed
                roll = True
                while roll:
                    if menuitem in PIPS:
                        self.rolls.append(str(menuitem))
                    warn_message, words, word_ids, hash = rolls(''.join(self.rolls) )

                    ans_hash = hexlify(hash).decode('utf-8')
                    middle = int(len(ans_hash)/2)
                    hash1 = ans_hash[:middle]
                    hash2 = ans_hash[middle:]

                    if ans_hash == "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855":
                        warn_message = "WARNING: Input is empty. This is a known wallet!" # overwrite low entropy warn message
                    if warn_message:
                        message = "%s\n%s" % (warn_message, words)
                    else:
                        message = words

                    scr = DiceRollsScreen(
                            title="Press 1-6 for each roll to mix in.",
                            note="%s rolls: %s\n-\n%s\n%s" % (len(self.rolls), ''.join(self.rolls), hash1, hash2 ),
                            message ="%s" % (message),
                    )
                    menuitem = await show_screen(scr)
                    if menuitem == USE_SEED:
                        print("TODO: USE SEED!")
                        roll = False
                    elif menuitem == ADD_ROLL:
                        roll = False
                    elif menuitem == BACK:
                        roll = False
                menuitem = await show_screen(Menu(buttons, title="Seed creation by rolling dice", last=(255, None)))
Пример #8
0
 async def create_wallet(self, derivation, xpub, prefix, version, show_screen):
     """Shows a wallet creation menu and passes descriptor to the wallets app"""
     net = NETWORKS[self.network]
     descriptors = OrderedDict({
         "zpub": ("wpkh(%s%s/{0,1}/*)" % (prefix, xpub), "Native Segwit"),
         "ypub": ("sh(wpkh(%s%s/{0,1}/*))" % (prefix, xpub), "Nested Segwit"),
         "legacy": ("pkh(%s%s/{0,1}/*)" % (prefix, xpub), "Legacy"),
         # multisig is not supported yet - requires cosigners app
     })
     if version == net["ypub"]:
         buttons = [
             (None, "Recommended"),
             descriptors.pop("ypub"),
             (None, "Other"),
         ]
     elif version == net["zpub"]:
         buttons = [
             (None, "Recommended"),
             descriptors.pop("zpub"),
             (None, "Other"),
         ]
     else:
         buttons = []
     buttons += [descriptors[k] for k in descriptors]
     menuitem = await show_screen(Menu(buttons, last=(255, None),
                                  title="Select wallet type to create"))
     if menuitem == 255:
         return
     else:
         # get wallet names from the wallets app
         s, _ = await self.communicate(BytesIO(b"listwallets"), app="wallets")
         names = json.load(s)
         if menuitem.startswith("pkh("):
             name_suggestion = "Legacy %d" % self.account
         elif menuitem.startswith("wpkh("):
             name_suggestion = "Native %d" % self.account
         elif menuitem.startswith("sh(wpkh("):
             name_suggestion = "Nested %d" % self.account
         else:
             name_suggestion = "Wallet %d" % self.account
         nn = name_suggestion
         i = 1
         # make sure we don't suggest existing name
         while name_suggestion in names:
             name_suggestion = "%s (%d)" % (nn, i)
             i += 1
         name = await show_screen(InputScreen(title="Name your wallet",
                 note="",
                 suggestion=name_suggestion,
                 min_length=1, strip=True
         ))
         if not name:
             return
         # send the wallets app addwallet command with descriptor
         data = "addwallet %s&%s" % (name, menuitem)
         stream = BytesIO(data.encode())
         await self.communicate(stream, app="wallets")
Пример #9
0
    async def save_menu(self, show_screen):
        buttons = [(0, "Specter-DIY (plaintext)"), (1, "Cold Card (json)")]
        # wait for menu selection
        menuitem = await show_screen(Menu(buttons, last=(255, None),
                                          title="Select a format"))

        # process the menu button:
        # back button
        if menuitem == 255:
            return None
        elif menuitem == 0:
            return self.export_specter_diy
        elif menuitem == 1:
            return self.export_coldcard
        return None
Пример #10
0
    async def select_file(self):

        buttons = []

        buttons += [(None, 'Internal storage')]
        buttons += self.load_files(self.flashpath)

        buttons += [(None, 'SD card')]
        if platform.is_sd_present():
            platform.mount_sdcard()
            buttons += self.load_files(self.sdpath)
            platform.unmount_sdcard()
        else:
            buttons += [(None, 'No SD card present')]

        return await self.show(
            Menu(buttons, title="Select a file", last=(None, "Cancel")))
Пример #11
0
    async def menu(self, show_screen, show_all=False):
        net = NETWORKS[self.network]
        buttons = [
            (None, "Recommended"),
            ("m/84h/%dh/0h" % net["bip32"], "Single key"),
            ("m/48h/%dh/0h/2h" % net["bip32"], "Multisig"),
            (None, "Other keys"),
        ]
        if show_all:
            coin = net["bip32"]
            buttons += [
                ("m/84h/%dh/0h" % coin,
                 "Single Native Segwit\nm/84h/%dh/0h" % coin),
                ("m/49h/%dh/0h" % coin,
                 "Single Nested Segwit\nm/49h/%dh/0h" % coin),
                (
                    "m/48h/%dh/0h/2h" % coin,
                    "Multisig Native Segwit\nm/48h/%dh/0h/2h" % coin,
                ),
                (
                    "m/48h/%dh/0h/1h" % coin,
                    "Multisig Nested Segwit\nm/48h/%dh/0h/1h" % coin,
                ),
            ]
        else:
            buttons += [(0, "Show more keys"), (1, "Enter custom derivation")]
        # wait for menu selection
        menuitem = await show_screen(Menu(buttons, last=(255, None)))

        # process the menu button:
        # back button
        if menuitem == 255:
            return False
        elif menuitem == 0:
            return await self.menu(show_screen, show_all=True)
        elif menuitem == 1:
            der = await show_screen(DerivationScreen())
            if der is not None:
                await self.show_xpub(der, show_screen)
                return True
        else:
            await self.show_xpub(menuitem, show_screen)
            return True
        return False
Пример #12
0
    async def storage_menu(self):
        """Manage storage"""
        buttons = [
            # id, text
            (None, "Manage keys on SD card and internal flash"),
            (0, "Save key"),
            (1, "Load key"),
            (2, "Delete key"),
        ]

        # disabled if SD card is not present
        buttons.append(
            (3, "Export recovery phrase to SD", platform.is_sd_present()))

        # we stay in this menu until back is pressed
        while True:
            # wait for menu selection
            menuitem = await self.show(Menu(buttons, last=(255, None)))
            # process the menu button:
            # back button
            if menuitem == 255:
                return
            elif menuitem == 0:
                filename = await self.save_mnemonic()
                if filename:
                    await self.show(
                        Alert("Success!",
                              "Your key is stored now.\n\nName: %s" % filename,
                              button_text="OK"))
            elif menuitem == 1:
                if await self.load_mnemonic():
                    await self.show(
                        Alert("Success!",
                              "Your key is loaded.",
                              button_text="OK"))
            elif menuitem == 2:
                if await self.delete_mnemonic():
                    await self.show(
                        Alert("Success!",
                              "Your key is deleted.",
                              button_text="OK"))
            elif menuitem == 3:
                await self.export_mnemonic()
Пример #13
0
 async def export_menu(self, show_screen):
     while True:
         buttons = [
             (None, "Export options"),
             (1, "Show QR code"),
             (2, "Save to SD card", platform.is_sd_present()),
         ]
         menuitem = await show_screen(
             Menu(buttons,
                  last=(255, None),
                  title="Export wallet %s" % self.name))
         desc = add_checksum(str(self.descriptor.branch(0)))
         obj = {
             "descriptor": desc,
             "label": self.name,
         }
         if self.descriptor.num_branches > 2:
             obj["branches"] = [
                 add_checksum(str(self.descriptor.branch(i)))
                 for i in range(self.descriptor.num_branches)
             ]
         if menuitem == 1:
             await show_screen(
                 QRAlert(
                     title="Export wallet %s" % self.name,
                     qr_width=450,
                     message=
                     "Scan this QR code with compatible software wallet",
                     qr_message=json.dumps(obj)))
         elif menuitem == 2:
             if not platform.is_sd_present():
                 raise WalletError("SD card is not present")
             platform.mount_sdcard()
             fname = "/sd/%s.json" % self.name
             with open(platform.fpath(fname), "w") as f:
                 json.dump(obj, f)
             platform.unmount_sdcard()
             await show_screen(
                 Alert("Success!",
                       "Wallet descriptor is written to\n\n%s" % fname))
         else:
             return
Пример #14
0
    async def storage_menu(self):
        """Manage storage and display of the recovery phrase"""
        enabled = self.connection.isCardInserted()
        buttons = [
            # id, text
            (None, "Smartcard storage"),
            (0, "Save key to the card", enabled),
            (1, "Load key from the card", enabled),
            (2, "Delete key from the card", enabled),
            (3, "Show recovery phrase"),
        ]

        # we stay in this menu until back is pressed
        while True:
            # wait for menu selection
            menuitem = await self.show(Menu(buttons, last=(255, None)))
            # process the menu button:
            # back button
            if menuitem == 255:
                return
            elif menuitem == 0:
                await self.save_mnemonic()
                await self.show(
                    Alert(
                        "Success!",
                        "Your key is stored on the smartcard now.",
                        button_text="OK",
                    ))
            elif menuitem == 1:
                await self.load_mnemonic()
                await self.show(
                    Alert("Success!", "Your key is loaded.", button_text="OK"))
            elif menuitem == 2:
                await self.delete_mnemonic()
                await self.show(
                    Alert(
                        "Success!",
                        "Your key is deleted from the smartcard.",
                        button_text="OK",
                    ))
            elif menuitem == 3:
                await self.show(MnemonicScreen(self.mnemonic))
Пример #15
0
 async def get_keypath(self,
                       title="Select media",
                       only_if_exist=True,
                       **kwargs):
     # enable / disable buttons
     enable_flash = (not only_if_exist) or platform.file_exists(
         self.flashpath)
     enable_sd = False
     if platform.is_sd_present():
         platform.mount_sdcard()
         enable_sd = (not only_if_exist) or platform.file_exists(
             self.sdpath)
         platform.unmount_sdcard()
     buttons = [
         (None, "Make your choice"),
         (self.flashpath, "Internal flash", enable_flash),
         (self.sdpath, "SD card", enable_sd),
     ]
     scr = Menu(buttons, title=title, last=(None, ), **kwargs)
     res = await self.show(scr)
     return res
Пример #16
0
    async def storage_menu(self):
        """Manage storage and display of the recovery phrase"""
        buttons = [
            # id, text
            (None, "Manage keys on SD card and internal flash"),
            (0, "Save key"),
            (1, "Load key"),
            (2, "Delete key"),
            (None, "Other"),
            (3, "Show recovery phrase"),
        ]

        # we stay in this menu until back is pressed
        while True:
            # wait for menu selection
            menuitem = await self.show(Menu(buttons, last=(255, None)))
            # process the menu button:
            # back button
            if menuitem == 255:
                return
            elif menuitem == 0:
                if await self.save_mnemonic():
                    await self.show(
                        Alert("Success!",
                              "Your key is stored now.",
                              button_text="OK"))
            elif menuitem == 1:
                if await self.load_mnemonic():
                    await self.show(
                        Alert("Success!",
                              "Your key is loaded.",
                              button_text="OK"))
            elif menuitem == 2:
                if await self.delete_mnemonic():
                    await self.show(
                        Alert("Success!",
                              "Your key is deleted.",
                              button_text="OK"))
            elif menuitem == 3:
                await self.show_mnemonic()
Пример #17
0
    async def menu(self, show_screen, show_all=False):
        net = NETWORKS[self.network]
        coin = net["bip32"]
        if not show_all:
            buttons = [
                (None, "Recommended"),
                ("m/84h/%dh/%dh" % (coin, self.account), "Single key"),
                ("m/48h/%dh/%dh/2h" % (coin, self.account), "Multisig"),
                (None, "Other keys"),
                (0, "Show more keys"),
                (2, "Change account number"),
                (1, "Enter custom derivation"),
                (3, "Export all keys to SD"),
            ]
        else:
            buttons = [
                (None, "Recommended"),
                (
                    "m/84h/%dh/%dh" % (coin, self.account),
                    "Single Native Segwit\nm/84h/%dh/%dh" % (coin, self.account)
                ),
                (
                    "m/48h/%dh/%dh/2h" % (coin, self.account),
                    "Multisig Native Segwit\nm/48h/%dh/%dh/2h" % (coin, self.account),
                ),
                (None, "Other keys"),
            ]
            if self.is_taproot_enabled:
                buttons.append((
                    "m/86h/%dh/%dh" % (coin, self.account),
                    "Single Taproot\nm/86h/%dh/%dh" % (coin, self.account)
                ))
            buttons.extend([
                (
                    "m/49h/%dh/%dh" % (coin, self.account),
                    "Single Nested Segwit\nm/49h/%dh/%dh" % (coin, self.account)
                ),
                (
                    "m/48h/%dh/%dh/1h" % (coin, self.account),
                    "Multisig Nested Segwit\nm/48h/%dh/%dh/1h" % (coin, self.account),
                ),
            ])
        # wait for menu selection
        menuitem = await show_screen(Menu(buttons, last=(255, None),
                                          title="Select the key",
                                          note="Current account number: %d" % self.account))

        # process the menu button:
        # back button
        if menuitem == 255:
            return False
        elif menuitem == 0:
            return await self.menu(show_screen, show_all=True)
        elif menuitem == 1:
            der = await show_screen(DerivationScreen())
            if der is not None:
                await self.show_xpub(der, show_screen)
                return True
        elif menuitem == 3:
            file_format = await self.save_menu(show_screen)
            if file_format:
                filename = self.save_all_to_sd(file_format)
                await show_screen(
                    Alert("Saved!",
                          "Public keys are saved to the file:\n\n%s" % filename,
                          button_text="Close")
                )
        elif menuitem == 2:
            account = await show_screen(NumericScreen(current_val=str(self.account)))
            if account and int(account) > 0x80000000:
                raise AppError('Account number too large')
            try:
                self.account = int(account)
            except:
                self.account = 0
            return await self.menu(show_screen)
        else:
            await self.show_xpub(menuitem, show_screen)
            return True
        return False
Пример #18
0
    async def storage_menu(self):
        """Manage storage"""
        enabled = self.connection.isCardInserted()
        buttons = [
            # id, text, enabled, color
            (None, "Smartcard storage"),
            (0, "Save key to the card", enabled),
            (1, "Load key from the card", enabled and self.is_key_saved),
            (2, "Delete key from the card", enabled and self.is_key_saved),
            (3, "Use a different card", enabled),
            (4, lv.SYMBOL.SETTINGS + " Get card info", enabled),
            # (5, lv.SYMBOL.TRASH + " Wipe the card", enabled, 0x951E2D),
        ]

        # we stay in this menu until back is pressed
        while True:
            # check updated status
            buttons[2] = (1, "Load key from the card", enabled
                          and self.is_key_saved)
            buttons[3] = (2, "Delete key from the card", enabled
                          and self.is_key_saved)
            note = "Card fingerprint: %s" % self.hexid
            # wait for menu selection
            menuitem = await self.show(
                Menu(buttons, note=note, last=(255, None)))
            # process the menu button:
            # back button
            if menuitem == 255:
                return
            elif menuitem == 0:
                await self.save_mnemonic()
                await self.show(
                    Alert(
                        "Success!",
                        "Your key is stored on the smartcard now.",
                        button_text="OK",
                    ))
            elif menuitem == 1:
                await self.load_mnemonic()
                await self.show(
                    Alert("Success!", "Your key is loaded.", button_text="OK"))
            elif menuitem == 2:
                if await self.show(
                        Prompt("Are you sure?",
                               "\n\nDelete the key from the card?")):
                    await self.delete_mnemonic()
                    await self.show(
                        Alert(
                            "Success!",
                            "Your key is deleted from the smartcard.",
                            button_text="OK",
                        ))
            elif menuitem == 3:
                if await self.show(
                        Prompt(
                            "Switching the smartcard",
                            "To use a different smartcard you need "
                            "to provide a PIN for current one first!\n\n"
                            "Continue?")):
                    self.lock()
                    await self.unlock()
                    self.lock()
                    self.applet.close_secure_channel()
                    self._userkey = None
                    await self.show(
                        Alert("Please swap the card",
                              "Now you can insert another card and set it up.",
                              button_text="Continue"))
                    await self.check_card(check_pin=True)
                    await self.unlock()
            elif menuitem == 4:
                await self.show_card_info()
            else:
                raise KeyStoreError("Invalid menu")
Пример #19
0
    async def menu(self, show_screen, show_all=False):
        net = NETWORKS[self.network]
        coin = net["bip32"]
        buttons = [
            (None, "Recommended"),
            ("m/84h/%dh/%dh" % (coin, self.account), "Single key"),
            ("m/48h/%dh/%dh/2h" % (coin, self.account), "Multisig"),
            (None, "Other keys"),
        ]
        if show_all:
            buttons += [
                ("m/84h/%dh/%dh" % (coin, self.account),
                 "Single Native Segwit\nm/84h/%dh/%dh" % (coin, self.account)),
                ("m/49h/%dh/%dh" % (coin, self.account),
                 "Single Nested Segwit\nm/49h/%dh/%dh" % (coin, self.account)),
                (
                    "m/48h/%dh/%dh/2h" % (coin, self.account),
                    "Multisig Native Segwit\nm/48h/%dh/%dh/2h" %
                    (coin, self.account),
                ),
                (
                    "m/48h/%dh/%dh/1h" % (coin, self.account),
                    "Multisig Nested Segwit\nm/48h/%dh/%dh/1h" %
                    (coin, self.account),
                ),
            ]
        else:
            buttons += [(0, "Show more keys"), (2, "Change account number"),
                        (1, "Enter custom derivation")]
        # wait for menu selection
        menuitem = await show_screen(
            Menu(buttons,
                 last=(255, None),
                 title="Select the key",
                 note="Current account number: %d" % self.account))

        # process the menu button:
        # back button
        if menuitem == 255:
            return False
        elif menuitem == 0:
            return await self.menu(show_screen, show_all=True)
        elif menuitem == 1:
            der = await show_screen(DerivationScreen())
            if der is not None:
                await self.show_xpub(der, show_screen)
                return True
        elif menuitem == 2:
            account = await show_screen(
                NumericScreen(current_val=str(self.account)))
            if account and int(account) > 0x80000000:
                raise AppError('Account number too large')
            try:
                self.account = int(account)
            except:
                self.account = 0
            return await self.menu(show_screen)
        else:
            await self.show_xpub(menuitem, show_screen)
            return True
        return False