573 lines
26 KiB
Python
573 lines
26 KiB
Python
# (c) Copyright 2018 by Coinkite Inc. This file is covered by license found in COPYING-CC.
|
|
#
|
|
# flow.py - Menu structure
|
|
#
|
|
from menu import MenuItem, PreloginToggleMenuItem, ToggleMenuItem, NonDefaultMenuItem, ShortcutItem
|
|
import version, charcodes
|
|
from glob import settings
|
|
|
|
from actions import *
|
|
from choosers import *
|
|
from mk4 import dev_enable_repl
|
|
from multisig import make_multisig_menu, import_multisig_nfc
|
|
from seed import make_ephemeral_seed_menu, make_seed_vault_menu, start_b39_pw
|
|
from address_explorer import address_explore
|
|
from drv_entro import drv_entro_start, password_entry
|
|
from backups import clone_start, clone_write_data
|
|
from xor_seed import xor_split_start, xor_restore_start
|
|
from countdowns import countdown_chooser
|
|
from paper import make_paper_wallet
|
|
from trick_pins import TrickPinMenu
|
|
from tapsigner import import_tapsigner_backup_file
|
|
from ccc import toggle_ccc_feature, sssp_spending_policy, sssp_feature_menu
|
|
|
|
# useful shortcut keys
|
|
from charcodes import KEY_QR, KEY_NFC
|
|
|
|
|
|
# Optional feature: HSM, depends on hardware
|
|
# - code for HSM support won't exist on some platforms, so don't call it
|
|
if version.supports_hsm:
|
|
from hsm import hsm_policy_available
|
|
from users import make_users_menu
|
|
else:
|
|
hsm_policy_available = False
|
|
make_users_menu = None
|
|
|
|
# Q related items
|
|
if version.has_battery:
|
|
from battery import battery_idle_timeout_chooser, brightness_chooser
|
|
from q1 import scan_and_bag
|
|
from notes import make_notes_menu
|
|
from teleport import kt_start_rx, kt_send_file_psbt
|
|
else:
|
|
battery_idle_timeout_chooser = None
|
|
brightness_chooser = None
|
|
scan_and_bag = None
|
|
make_notes_menu = None
|
|
kt_start_rx = None
|
|
kt_send_file_psbt = None
|
|
|
|
#
|
|
# NOTE: "Always In Title Case"
|
|
#
|
|
# - try to keep harmless things as first item: so double-tap of OK does no harm
|
|
|
|
#
|
|
# PREDICATES
|
|
# all predicates must be boolean value, or a callable to be evaluated at runtime
|
|
#
|
|
|
|
def has_se_secrets():
|
|
# SE secret check, return False if only tmp secret is set
|
|
from pincodes import pa
|
|
return not pa.is_secret_blank()
|
|
|
|
def has_pin():
|
|
from pincodes import pa
|
|
return not pa.is_blank()
|
|
|
|
def has_secrets():
|
|
# Secret is loaded, may be from SE or tmp
|
|
from pincodes import pa
|
|
return pa.has_secrets()
|
|
|
|
qr_and_has_secrets = has_secrets if version.has_qr else False
|
|
|
|
def nfc_enabled():
|
|
from glob import NFC
|
|
return bool(NFC)
|
|
|
|
def vdisk_enabled():
|
|
return bool(settings.get('vidsk', 0))
|
|
|
|
def is_not_tmp():
|
|
from pincodes import pa
|
|
return not bool(pa.tmp_value)
|
|
|
|
def is_tmp():
|
|
from pincodes import pa
|
|
return bool(pa.tmp_value)
|
|
|
|
def has_real_secret():
|
|
from pincodes import pa
|
|
return (not pa.is_secret_blank()) and (not pa.tmp_value)
|
|
|
|
def word_based_seed():
|
|
return settings.get("words", True)
|
|
|
|
def hsm_available():
|
|
# contains hsm feature + can it be used (needs se2 secret and no tmp active)
|
|
return version.supports_hsm and has_real_secret()
|
|
|
|
def qr_and_ms():
|
|
# has QR scanner, and at least one MS wallet
|
|
if not version.has_qr: return False
|
|
return bool(settings.get('multisig', False))
|
|
|
|
def has_pushtx_url():
|
|
# they want to use PushTX feature
|
|
return bool(settings.get("ptxurl", False))
|
|
|
|
# Spending Policy (Hobbled mode) predicates.
|
|
#
|
|
def is_hobble_testdrive():
|
|
from pincodes import pa
|
|
return (pa.hobbled_mode == 2)
|
|
|
|
def sssp_related_keys():
|
|
return sssp_spending_policy('okeys')
|
|
|
|
def sssp_allow_passphrase():
|
|
return word_based_seed() and sssp_related_keys()
|
|
|
|
def sssp_allow_notes():
|
|
return settings.get("secnap", False) and sssp_spending_policy('notes')
|
|
|
|
def sssp_allow_vault():
|
|
return settings.master_get('seedvault') and sssp_related_keys()
|
|
|
|
async def goto_home(*a):
|
|
goto_top_menu()
|
|
|
|
|
|
HWTogglesMenu = [
|
|
ToggleMenuItem('USB Port', 'du', ['Default On', 'Disable USB'], invert=True,
|
|
on_change=change_usb_disable, story='''\
|
|
Blocks any data over USB port. Useful when your plan is air-gap usage.'''),
|
|
ToggleMenuItem('Virtual Disk', 'vidsk', ['Default Off', 'Enable', 'Enable & Auto'],
|
|
on_change=change_virtdisk_enable,
|
|
story='''Coldcard can emulate a virtual disk drive (4MB) where new PSBT files \
|
|
can be saved. Signed PSBT files (transactions) will also be saved here. \n\
|
|
In "auto" mode, selects PSBT as soon as written.'''),
|
|
ToggleMenuItem('NFC Sharing', 'nfc', ['Default Off', 'Enable NFC'], on_change=change_nfc_enable,
|
|
story='''\
|
|
NFC (Near Field Communications) allows a phone to "tap" to send and receive data \
|
|
with the Coldcard.''',
|
|
predicate=version.has_nfc),
|
|
]
|
|
|
|
# Mostly pre-login values here.
|
|
LoginPrefsMenu = [
|
|
# xxxxxxxxxxxxxxxx
|
|
MenuItem('Change Main PIN', f=main_pin_changer),
|
|
NonDefaultMenuItem('Trick PINs', 'tp', menu=TrickPinMenu.make_menu, predicate=has_real_secret),
|
|
NonDefaultMenuItem('Set Nickname', 'nick', prelogin=True, f=pick_nickname),
|
|
NonDefaultMenuItem('Scramble Keys', 'rngk', prelogin=True, f=pick_scramble, default_value=0),
|
|
NonDefaultMenuItem('Kill Key', 'kbtn', prelogin=True, f=pick_killkey),
|
|
NonDefaultMenuItem('Login Countdown', 'lgto', prelogin=True, chooser=countdown_chooser),
|
|
NonDefaultMenuItem('MicroSD 2FA', 'sd2fa', menu=microsd_2fa, predicate=has_real_secret),
|
|
PreloginToggleMenuItem('Calculator Login', 'calc', ['Default Off', 'Calculator Login'],
|
|
story=('Boots into calculator mode. Enter your PIN as formula to login, '
|
|
'or 12- to see prefix words. Normal calculator math works too.'),
|
|
predicate=version.has_qwerty),
|
|
MenuItem('Test Login Now', f=login_now, arg=1),
|
|
]
|
|
|
|
|
|
# obscure settings, not more dangerous, just more personal
|
|
BuriedSettingsMenu = [
|
|
ToggleMenuItem('Home Menu XFP', 'hmx', ['Only Tmp', 'Always Show'],
|
|
story=('Forces display of XFP (seed fingerprint) '
|
|
'at top of main menu. Normally, XFP is shown only when '
|
|
'temporary seed is active.\n\n'
|
|
'Master seed is displayed as <XFP>, temporary seeds as [XFP].'),
|
|
predicate=has_real_secret,
|
|
on_change=goto_home),
|
|
ToggleMenuItem('Menu Wrapping', 'wa', ['Default', 'Always Wrap'],
|
|
story='''When enabled, allows scrolling past menu top/bottom \
|
|
(wrap around). By default, this only happens in menus whose length is greater than 10.'''),
|
|
]
|
|
|
|
SettingsMenu = [
|
|
# xxxxxxxxxxxxxxxx
|
|
MenuItem('Login Settings', menu=LoginPrefsMenu),
|
|
MenuItem('Hardware On/Off', menu=HWTogglesMenu),
|
|
NonDefaultMenuItem('Multisig Wallets', 'multisig',
|
|
menu=make_multisig_menu, predicate=has_secrets, shortcut='m'),
|
|
NonDefaultMenuItem('NFC Push Tx', 'ptxurl', menu=pushtx_setup_menu),
|
|
MenuItem('Display Units', chooser=value_resolution_chooser),
|
|
MenuItem('Max Network Fee', chooser=max_fee_chooser),
|
|
MenuItem('Idle Timeout', chooser=idle_timeout_chooser),
|
|
MenuItem('Idle Timeout (on battery)', chooser=battery_idle_timeout_chooser,
|
|
predicate=version.has_battery),
|
|
MenuItem('LCD Brightness (on battery)', chooser=brightness_chooser,
|
|
predicate=version.has_battery),
|
|
ToggleMenuItem('Delete PSBTs', 'del', ['Default Keep', 'Delete PSBTs'],
|
|
story='''\
|
|
PSBT files (on SDCard) will be blanked & deleted after they are used. \
|
|
The signed transaction will be named <TXID>.txn, so the file name does not leak information.
|
|
|
|
MS-DOS tools should not be able to find the PSBT data (ie. undelete), but forensic tools \
|
|
which take apart the flash chips of the SDCard may still be able to find the \
|
|
data or filenames.'''),
|
|
ToggleMenuItem('Keyboard EMU', 'emu', ['Default Off', 'Enable'],
|
|
on_change=usb_keyboard_emulation,
|
|
predicate=has_secrets, # cannot generate BIP85 passwords without secret
|
|
story='''This mode adds a top-level menu item for typing \
|
|
deterministically-generated passwords (BIP-85), directly into an \
|
|
attached USB computer (as an emulated keyboard).'''),
|
|
MenuItem('Buried Settings', menu=BuriedSettingsMenu),
|
|
]
|
|
|
|
XpubExportMenu = [
|
|
# xxxxxxxxxxxxxxxx
|
|
MenuItem("Segwit (BIP-84)", f=export_xpub, arg=84),
|
|
MenuItem("Classic (BIP-44)", f=export_xpub, arg=44),
|
|
MenuItem("P2WPKH/P2SH "+("(BIP-49)"if version.has_qwerty else "(49)"), f=export_xpub, arg=49),
|
|
MenuItem("Master XPUB", f=export_xpub, arg=0),
|
|
MenuItem("Current XFP", f=export_xpub, arg=-1),
|
|
]
|
|
|
|
WalletExportMenu = [
|
|
# xxxxxxxxxxxxxxxx
|
|
MenuItem("Sparrow", f=named_generic_skeleton, arg="Sparrow"),
|
|
MenuItem("Cove", f=named_generic_skeleton, arg="Cove"),
|
|
MenuItem("Bitcoin Core", f=bitcoin_core_skeleton),
|
|
MenuItem("Nunchuk", f=named_generic_skeleton, arg="Nunchuk"),
|
|
MenuItem("Bull Bitcoin", f=ss_descriptor_skeleton,
|
|
arg=(True, [AF_P2WPKH], "", "bull-bitcoin.txt", KEY_QR)),
|
|
MenuItem("Zeus", f=ss_descriptor_skeleton,
|
|
arg=(True, [AF_P2WPKH, AF_P2WPKH_P2SH], "Zeus Wallet", "zeus-export.txt", None)),
|
|
MenuItem("Electrum Wallet", f=electrum_skeleton),
|
|
MenuItem("Wasabi Wallet", f=wasabi_skeleton),
|
|
MenuItem("Fully Noded", f=named_generic_skeleton, arg="Fully Noded"),
|
|
MenuItem("Unchained", f=unchained_capital_export),
|
|
MenuItem("Theya", f=named_generic_skeleton, arg="Theya"),
|
|
MenuItem("Bitcoin Safe", f=named_generic_skeleton, arg="Bitcoin Safe"),
|
|
MenuItem("Samourai Postmix", f=samourai_post_mix_descriptor_export),
|
|
MenuItem("Samourai Premix", f=samourai_pre_mix_descriptor_export),
|
|
# MenuItem("Samourai BadBank", f=samourai_bad_bank_descriptor_export), # not released yet
|
|
MenuItem("Descriptor", f=ss_descriptor_skeleton),
|
|
MenuItem("Generic JSON", f=generic_skeleton),
|
|
MenuItem("Export XPUB", menu=XpubExportMenu),
|
|
MenuItem("Key Expression", f=key_expression_skeleton),
|
|
MenuItem("Dump Summary", predicate=has_secrets, f=dump_summary),
|
|
]
|
|
|
|
# useful even if no secrets, may operate on VDisk or SDCard when inserted
|
|
FileMgmtMenu = [
|
|
# xxxxxxxxxxxxxxxx
|
|
MenuItem("Verify Backup", f=verify_backup),
|
|
MenuItem("Backup System", predicate=has_secrets, f=backup_everything),
|
|
MenuItem('Export Wallet', predicate=has_secrets, menu=WalletExportMenu), #dup elsewhere
|
|
MenuItem('Sign Text File', predicate=has_secrets, f=sign_message_on_sd),
|
|
MenuItem('Batch Sign PSBT', predicate=has_secrets, f=batch_sign),
|
|
MenuItem('Teleport Multisig PSBT', predicate=qr_and_has_secrets, f=kt_send_file_psbt),
|
|
MenuItem('List Files', f=list_files),
|
|
MenuItem('Verify Sig File', f=verify_sig_file),
|
|
MenuItem('NFC File Share', predicate=nfc_enabled, f=nfc_share_file, shortcut=KEY_NFC),
|
|
MenuItem('BBQr File Share', predicate=version.has_qr, f=qr_share_file, arg=True),
|
|
MenuItem('QR File Share', predicate=version.has_qr, f=qr_share_file, shortcut=KEY_QR),
|
|
MenuItem('Clone Coldcard', predicate=has_secrets, f=clone_write_data),
|
|
MenuItem('Format SD Card', f=wipe_sd_card),
|
|
MenuItem('Format RAM Disk', predicate=vdisk_enabled, f=wipe_vdisk),
|
|
]
|
|
|
|
UpgradeMenu = [
|
|
# xxxxxxxxxxxxxxxx
|
|
MenuItem('Show Version', f=show_version),
|
|
MenuItem('From MicroSD', f=microsd_upgrade, arg=False),
|
|
MenuItem('From VirtDisk', predicate=vdisk_enabled, f=microsd_upgrade, arg=True), # force_vdisk=True
|
|
]
|
|
|
|
DevelopersMenu = [
|
|
# xxxxxxxxxxxxxxxx
|
|
MenuItem("Serial REPL", f=dev_enable_repl),
|
|
MenuItem('Warm Reset', f=reset_self),
|
|
MenuItem("Restore Bkup", f=restore_backup_dev),
|
|
MenuItem("BKPW Override", menu=bkpw_override, predicate=has_secrets),
|
|
MenuItem('Reflash GPU', f=reflash_gpu, predicate=version.has_qwerty),
|
|
]
|
|
|
|
AdvancedVirginMenu = [ # No PIN, no secrets yet (factory fresh)
|
|
# xxxxxxxxxxxxxxxx
|
|
MenuItem("View Identity", f=view_ident),
|
|
MenuItem('Paper Wallets', f=make_paper_wallet),
|
|
MenuItem('Perform Selftest', f=start_selftest),
|
|
MenuItem('Secure Logout', f=logout_now, predicate=not version.has_battery),
|
|
]
|
|
|
|
AdvancedPinnedVirginMenu = [ # Has PIN but no secrets yet
|
|
# xxxxxxxxxxxxxxxx
|
|
MenuItem("View Identity", f=view_ident),
|
|
MenuItem("Temporary Seed", menu=make_ephemeral_seed_menu),
|
|
MenuItem("Upgrade Firmware", menu=UpgradeMenu, predicate=is_not_tmp),
|
|
MenuItem("File Management", menu=FileMgmtMenu),
|
|
MenuItem("Key Teleport (start)", f=kt_start_rx, predicate=version.has_qr),
|
|
MenuItem('Paper Wallets', f=make_paper_wallet),
|
|
MenuItem('Perform Selftest', f=start_selftest),
|
|
MenuItem("I Am Developer.", menu=maybe_dev_menu),
|
|
MenuItem('Secure Logout', f=logout_now, predicate=not version.has_battery),
|
|
]
|
|
|
|
DebugFunctionsMenu = [
|
|
# xxxxxxxxxxxxxxxx
|
|
MenuItem("Keyboard Test", f=keyboard_test),
|
|
MenuItem('BBQr Demo', f=debug_bbqr_test, predicate=version.has_qwerty),
|
|
MenuItem('Debug: assert', f=debug_assert),
|
|
MenuItem('Debug: except', f=debug_except),
|
|
MenuItem('Check: BL FW', f=check_firewall_read),
|
|
MenuItem('Warm Reset', f=reset_self),
|
|
#MenuItem("Perform Selftest", f=start_selftest),
|
|
]
|
|
|
|
SeedXORMenu = [
|
|
# xxxxxxxxxxxxxxxx
|
|
MenuItem("Split Existing", f=xor_split_start, predicate=word_based_seed),
|
|
MenuItem("Restore Seed XOR", f=xor_restore_start),
|
|
]
|
|
|
|
SeedFunctionsMenu = [
|
|
MenuItem('View Seed Words', f=view_seed_words), # text is a little wrong sometimes, rare
|
|
MenuItem('Seed XOR', menu=SeedXORMenu),
|
|
MenuItem("Destroy Seed", f=clear_seed, predicate=has_real_secret),
|
|
MenuItem('Lock Down Seed', f=convert_ephemeral_to_master, predicate=is_tmp),
|
|
MenuItem('Export SeedQR', f=export_seedqr, predicate=word_based_seed),
|
|
]
|
|
|
|
DangerZoneMenu = [
|
|
# xxxxxxxxxxxxxxxx
|
|
MenuItem("Debug Functions", menu=DebugFunctionsMenu), # actually harmless
|
|
MenuItem("Seed Functions", menu=SeedFunctionsMenu),
|
|
MenuItem("I Am Developer.", menu=maybe_dev_menu),
|
|
ToggleMenuItem('Seed Vault', 'seedvault', ['Default Off', 'Enable'],
|
|
on_change=change_seed_vault,
|
|
story=("Enable Seed Vault? Adds prompt to store temporary seeds "
|
|
"into Seed Vault, where they can easily be reused later.\n\n"
|
|
"WARNING: Seed Vault is encrypted (AES-256-CTR) by your seed,"
|
|
" but not held directly inside secure elements. Backups are required"
|
|
" after any change to vault! Recommended for experiments or temporary use."),
|
|
predicate=has_real_secret),
|
|
MenuItem('Perform Selftest', f=start_selftest), # little harmful
|
|
MenuItem("Set High-Water", f=set_highwater),
|
|
MenuItem('Wipe HSM Policy', f=wipe_hsm_policy, predicate=hsm_policy_available),
|
|
MenuItem('Clear OV cache', f=wipe_ovc),
|
|
MenuItem("Clear Address cache" if version.has_qwerty else "Clear Addr cache", f=wipe_address_cache),
|
|
ToggleMenuItem("Sighash Checks", "sighshchk", ["Default: Block", "Warn"],
|
|
invert=True,
|
|
story='''\
|
|
If you disable sighash flag restrictions, and ignore the \
|
|
warnings, funds can be stolen by specially crafted PSBT or MitM.
|
|
|
|
Keep blocked unless you intend to sign special transactions.'''),
|
|
ToggleMenuItem('Testnet Mode', 'chain', ['Bitcoin', 'Testnet4', 'Regtest'],
|
|
value_map=['BTC', 'XTN', 'XRT'],
|
|
on_change=change_which_chain,
|
|
story="Testnet must only be used by developers because \
|
|
correctly- crafted transactions signed on Testnet could be broadcast on Mainnet."),
|
|
ToggleMenuItem('AE Start Index', 'aei', ['Default Off', 'Enable'], story=(
|
|
"Enable this option to add new menu item to Address Explorer "
|
|
"allowing override of start index. By default start index is zero.\n\n"
|
|
"WARNING: Some wallets will not recognize addresses that are past their gap limit"
|
|
" and your deposits will seem to disappear."),
|
|
predicate=has_secrets),
|
|
ToggleMenuItem('B85 Idx Values', 'b85max', ['Default Off', 'Unlimited'],
|
|
story=("Allow unlimited indexes for BIP-85 derivations?\n\n"
|
|
"DANGER: If you forget this index number, getting your funds "
|
|
"back will be a difficult search problem."),
|
|
predicate=has_secrets),
|
|
MenuItem('Settings Space', f=show_settings_space),
|
|
MenuItem('MCU Key Slots', f=show_mcu_keys_left),
|
|
MenuItem('Bless Firmware', f=bless_flash), # no need for this anymore?
|
|
MenuItem("Wipe LFS", f=wipe_filesystem), # kills other-seed settings, HSM stuff, addr cache
|
|
MenuItem("Nuke Device", f=nuke_device),
|
|
]
|
|
|
|
BackupStuffMenu = [
|
|
# xxxxxxxxxxxxxxxx
|
|
MenuItem("Backup System", f=backup_everything),
|
|
MenuItem("Verify Backup", f=verify_backup),
|
|
MenuItem("Restore Backup", f=need_clear_seed), # just a UX msg really
|
|
MenuItem('Clone Coldcard', predicate=has_secrets, f=clone_write_data),
|
|
]
|
|
|
|
NFCToolsMenu = [
|
|
MenuItem('Sign PSBT', f=nfc_sign_psbt),
|
|
MenuItem('Show Address', f=nfc_show_address),
|
|
MenuItem('Sign Message', f=nfc_sign_msg),
|
|
MenuItem('Verify Sig File', f=nfc_sign_verify),
|
|
MenuItem('Verify Address', f=nfc_address_verify),
|
|
MenuItem('File Share', f=nfc_share_file),
|
|
MenuItem('Import Multisig', f=import_multisig_nfc),
|
|
MenuItem('Push Transaction', f=nfc_pushtx_file, predicate=has_pushtx_url),
|
|
]
|
|
|
|
|
|
SpendingPolicySubMenu = [
|
|
NonDefaultMenuItem('Single-Signer', 'sssp', f=sssp_feature_menu, predicate=has_real_secret),
|
|
NonDefaultMenuItem('Co-Sign Multi.' if not version.has_qwerty else 'Co-Sign Multisig (CCC)',
|
|
'ccc', f=toggle_ccc_feature, predicate=is_not_tmp),
|
|
ToggleMenuItem('HSM Mode', 'hsmcmd', ['Default Off', 'Enable'],
|
|
story=("Enable HSM? Enables all user management commands, and other HSM-only USB commands. "
|
|
"By default these commands are disabled."),
|
|
predicate=hsm_available),
|
|
MenuItem('User Management', menu=make_users_menu,
|
|
predicate=lambda: hsm_available() and settings.get('hsmcmd', False)),
|
|
]
|
|
|
|
AdvancedNormalMenu = [
|
|
# xxxxxxxxxxxxxxxx
|
|
MenuItem("Backup", menu=BackupStuffMenu),
|
|
MenuItem('Export Wallet', predicate=has_secrets, menu=WalletExportMenu, shortcut='x'), # also inside FileMgmt
|
|
MenuItem("Upgrade Firmware", menu=UpgradeMenu, predicate=is_not_tmp),
|
|
MenuItem("File Management", menu=FileMgmtMenu),
|
|
NonDefaultMenuItem('Secure Notes & Passwords', 'secnap', menu=make_notes_menu,
|
|
predicate=version.has_qwerty),
|
|
MenuItem('Derive Seed B85' if not version.has_qwerty else 'Derive Seeds (BIP-85)',
|
|
f=drv_entro_start),
|
|
MenuItem("View Identity", f=view_ident),
|
|
MenuItem("Temporary Seed", menu=make_ephemeral_seed_menu),
|
|
MenuItem("Key Teleport (start)", f=kt_start_rx, predicate=version.has_qr),
|
|
MenuItem("Spending Policy", menu=SpendingPolicySubMenu,shortcut='s',predicate=has_real_secret),
|
|
MenuItem('Paper Wallets', f=make_paper_wallet),
|
|
MenuItem('NFC Tools', predicate=nfc_enabled, menu=NFCToolsMenu, shortcut=KEY_NFC),
|
|
MenuItem("Danger Zone", menu=DangerZoneMenu, shortcut='z'),
|
|
]
|
|
|
|
# needs to create main wallet PIN
|
|
VirginSystem = [
|
|
# xxxxxxxxxxxxxxxx
|
|
MenuItem('Choose PIN Code', f=initial_pin_setup),
|
|
MenuItem('Advanced/Tools', menu=AdvancedVirginMenu, shortcut='t'),
|
|
MenuItem('Bag Number', f=show_bag_number),
|
|
MenuItem('Help', f=virgin_help, predicate=not version.has_qwerty),
|
|
]
|
|
|
|
ImportWallet = [
|
|
MenuItem("12 Words", menu=start_seed_import, arg=12),
|
|
MenuItem("18 Words", menu=start_seed_import, arg=18),
|
|
MenuItem("24 Words", menu=start_seed_import, arg=24),
|
|
MenuItem('Scan QR Code', predicate=version.has_qr,
|
|
shortcut=KEY_QR, f=scan_any_qr, arg=(True, False)),
|
|
MenuItem("Restore Backup", f=restore_backup, arg=False), # tmp=False
|
|
MenuItem("Clone Coldcard", menu=clone_start),
|
|
MenuItem("Import XPRV", f=import_xprv, arg=False), # ephemeral=False
|
|
MenuItem("Tapsigner Backup", f=import_tapsigner_backup_file, arg=False),
|
|
MenuItem("Seed XOR", f=xor_restore_start),
|
|
]
|
|
|
|
SeedFromDiceMenu = [
|
|
MenuItem("12 Word Dice Roll", f=new_from_dice, arg=12),
|
|
MenuItem("24 Word Dice Roll", f=new_from_dice, arg=24),
|
|
]
|
|
|
|
NewSeedMenu = [
|
|
MenuItem("12 Words", f=pick_new_seed, arg=12),
|
|
MenuItem("24 Words", f=pick_new_seed, arg=24),
|
|
MenuItem("Advanced", menu=SeedFromDiceMenu),
|
|
]
|
|
|
|
# has PIN, but no secret seed yet
|
|
EmptyWallet = [
|
|
# xxxxxxxxxxxxxxxx
|
|
MenuItem('New Seed Words', menu=NewSeedMenu),
|
|
MenuItem('Import Existing', menu=ImportWallet),
|
|
MenuItem("Migrate Coldcard", menu=clone_start),
|
|
MenuItem("Key Teleport (start)", f=kt_start_rx, predicate=version.has_qr),
|
|
MenuItem('Help', f=virgin_help, predicate=not version.has_qwerty),
|
|
MenuItem('Advanced/Tools', menu=AdvancedPinnedVirginMenu, shortcut='t'),
|
|
MenuItem('Settings', menu=SettingsMenu),
|
|
ShortcutItem(KEY_QR, predicate=version.has_qr, f=scan_any_qr, arg=(True, False)),
|
|
]
|
|
|
|
# In operation, normal system, after a good PIN received.
|
|
# - key shortcuts in place for all items that will be shown on Q
|
|
NormalSystem = [
|
|
# xxxxxxxxxxxxxxxx
|
|
MenuItem('Ready To Sign', f=ready2sign, shortcut='r'),
|
|
MenuItem('Passphrase', menu=start_b39_pw, predicate=word_based_seed, shortcut='p'),
|
|
MenuItem('Scan Any QR Code', predicate=version.has_qr,
|
|
shortcut=KEY_QR, f=scan_any_qr, arg=(False, True)),
|
|
MenuItem('Start HSM Mode', f=start_hsm_menu_item, predicate=hsm_policy_available),
|
|
MenuItem("Address Explorer", menu=address_explore, shortcut='x'),
|
|
MenuItem('Secure Notes & Passwords', menu=make_notes_menu, shortcut='n',
|
|
predicate=lambda: version.has_qwerty and settings.get("secnap", False)),
|
|
MenuItem('Type Passwords', f=password_entry, shortcut='t',
|
|
predicate=lambda: settings.get("emu", False) and has_secrets()),
|
|
MenuItem('Seed Vault', menu=make_seed_vault_menu, shortcut='v',
|
|
predicate=lambda: settings.master_get('seedvault') and has_secrets()),
|
|
MenuItem('Advanced/Tools', menu=AdvancedNormalMenu, shortcut='t'),
|
|
MenuItem('Settings', menu=SettingsMenu, shortcut='s'),
|
|
MenuItem('Secure Logout', f=logout_now, predicate=not version.has_battery),
|
|
ShortcutItem(KEY_NFC, predicate=nfc_enabled, menu=NFCToolsMenu),
|
|
]
|
|
|
|
# Shown until unit is put into a numbered bag
|
|
FactoryMenu = [
|
|
MenuItem('Bag Me Now', f=scan_and_bag),
|
|
MenuItem('Version: ' + version.get_mpy_version()[1], f=show_version),
|
|
MenuItem('DFU Upgrade', f=start_dfu, shortcut='u'),
|
|
MenuItem('Ship W/O Bag', f=ship_wo_bag),
|
|
MenuItem("Debug Functions", menu=DebugFunctionsMenu, shortcut='f'),
|
|
MenuItem("Perform Selftest", f=start_selftest, shortcut='s'),
|
|
]
|
|
|
|
# Special menus for hobbled mode where we have a (single signer) spending policy in effect.
|
|
# - no access to secrets, backups, firmware up/downgrades.
|
|
# - secure notes, but readonly; can be disabled completely.
|
|
# - key teleport, but only for PSBT & multisig purposes.
|
|
# - can only be enabled after we have secrets, so no need for has_secrets tests here
|
|
#
|
|
|
|
# Slightly limited file menu when hobbled.
|
|
# - no backup/restore
|
|
HobbledFileMgmtMenu = [
|
|
# xxxxxxxxxxxxxxxx
|
|
MenuItem('Sign Text File', f=sign_message_on_sd),
|
|
MenuItem('Batch Sign PSBT', f=batch_sign),
|
|
MenuItem('List Files', f=list_files),
|
|
MenuItem('Export Wallet', menu=WalletExportMenu), # dup under Adv/Tools
|
|
MenuItem('Verify Sig File', f=verify_sig_file),
|
|
MenuItem('NFC File Share', predicate=nfc_enabled, f=nfc_share_file, shortcut=KEY_NFC),
|
|
MenuItem('BBQr File Share', predicate=version.has_qr, f=qr_share_file, arg=True),
|
|
MenuItem('QR File Share', predicate=version.has_qr, f=qr_share_file, shortcut=KEY_QR),
|
|
MenuItem('Format SD Card', f=wipe_sd_card),
|
|
MenuItem('Format RAM Disk', predicate=vdisk_enabled, f=wipe_vdisk),
|
|
]
|
|
|
|
# NFC tools when hobbled: not much different.
|
|
HobbledNFCToolsMenu = [
|
|
MenuItem('Sign PSBT', f=nfc_sign_psbt),
|
|
MenuItem('Show Address', f=nfc_show_address),
|
|
MenuItem('Sign Message', f=nfc_sign_msg),
|
|
MenuItem('Verify Sig File', f=nfc_sign_verify),
|
|
MenuItem('Verify Address', f=nfc_address_verify),
|
|
MenuItem('File Share', f=nfc_share_file),
|
|
MenuItem('Push Transaction', f=nfc_pushtx_file, predicate=has_pushtx_url),
|
|
]
|
|
|
|
# Very limited advanced menu when hobbled.
|
|
HobbledAdvancedMenu = [
|
|
# xxxxxxxxxxxxxxxx
|
|
MenuItem("File Management", menu=HobbledFileMgmtMenu),
|
|
MenuItem('Export Wallet', menu=WalletExportMenu, shortcut='x'), # also inside FileMgmt
|
|
MenuItem('Teleport Multisig PSBT', predicate=qr_and_ms, f=kt_send_file_psbt),
|
|
MenuItem("View Identity", f=view_ident),
|
|
MenuItem("Temporary Seed", menu=make_ephemeral_seed_menu, predicate=sssp_related_keys),
|
|
MenuItem('Paper Wallets', f=make_paper_wallet),
|
|
MenuItem('NFC Tools', predicate=nfc_enabled, menu=HobbledNFCToolsMenu, shortcut=KEY_NFC),
|
|
MenuItem('Show %s Version' % ("Firmware" if version.has_qwerty else "FW"), f=show_version),
|
|
MenuItem("Destroy Seed", f=clear_seed, predicate=has_real_secret),
|
|
]
|
|
|
|
# Main menu when a spending policy (hobbled) is in effect.
|
|
HobbledTopMenu = [
|
|
# xxxxxxxxxxxxxxxx
|
|
MenuItem('Ready To Sign', f=ready2sign, shortcut='r'),
|
|
MenuItem('Passphrase', menu=start_b39_pw, predicate=sssp_allow_passphrase, shortcut='p'),
|
|
MenuItem('Scan Any QR Code', predicate=version.has_qr, f=scan_any_qr, arg=(False, True),
|
|
shortcut=KEY_QR),
|
|
MenuItem("Address Explorer", menu=address_explore, shortcut='x'),
|
|
MenuItem('Secure Notes & Passwords', menu=make_notes_menu, predicate=sssp_allow_notes,
|
|
shortcut='n'),
|
|
MenuItem('Type Passwords', f=password_entry, shortcut='t',
|
|
predicate=lambda: settings.get("emu", False) and sssp_related_keys()),
|
|
MenuItem('Seed Vault', menu=make_seed_vault_menu, predicate=sssp_allow_vault,
|
|
shortcut='v'),
|
|
MenuItem('Advanced/Tools', menu=HobbledAdvancedMenu, shortcut='t'),
|
|
MenuItem('Secure Logout', f=logout_now, predicate=not version.has_battery),
|
|
MenuItem('EXIT TEST DRIVE', f=sssp_feature_menu, predicate=is_hobble_testdrive),
|
|
ShortcutItem(KEY_NFC, predicate=nfc_enabled, menu=HobbledNFCToolsMenu),
|
|
]
|