seed vault optimizations

(cherry picked from commit 05a08b6ff8)
This commit is contained in:
Peter D. Gray 2023-10-06 11:51:24 -04:00 committed by doc-hex
parent 28c0fb4516
commit 0f43069e6c
13 changed files with 186 additions and 179 deletions

View File

@ -469,7 +469,7 @@ async def pick_nickname(*a):
# Value is not stored with normal settings, it's part of "prelogin" settings
# which are encrypted with zero-key.
s = SettingsObject()
s = SettingsObject.prelogin()
nick = s.get('nick', '')
if not nick:
@ -768,7 +768,7 @@ async def version_migration():
if had_delay:
from nvstore import SettingsObject
settings.remove_key('lgto')
s = SettingsObject()
s = SettingsObject.prelogin()
s.set('lgto', had_delay)
s.save()
del s
@ -942,7 +942,7 @@ async def restore_main_secret(*a):
escape = None
msg = "Restore main wallet and its settings?\n\n"
if not await in_seed_vault():
if not in_seed_vault():
msg += (
"Press OK to forget current temporary wallet "
"settings, or press (1) to save & keep "
@ -2245,10 +2245,11 @@ async def change_seed_vault(is_enabled):
# user has changed seed vault enable/disable flag
from glob import settings
if (not is_enabled) and settings.get('seeds'):
# restore it
settings.set('seedvault', 1)
await ux_show_story("Please remove all seeds from the vault before disabling")
if (not is_enabled) and settings.master_get('seeds'):
# problem: they still have some seeds... also this path blocks
# disable from within a tmp seed
settings.set('seedvault', 1) # restore it
await ux_show_story("Please remove all seeds from the vault before disabling.")
return

View File

@ -67,7 +67,7 @@ def value_resolution_chooser():
def scramble_keypad_chooser():
# rngk = randomize keypad for PIN entry
s = SettingsObject()
s = SettingsObject.prelogin()
which = s.get('rngk', 0)
del s
@ -75,7 +75,7 @@ def scramble_keypad_chooser():
def set(idx, text):
# save it, but "outside" of login PIN
s = SettingsObject()
s = SettingsObject.prelogin()
s.set('rngk', idx)
s.save()
del s
@ -85,7 +85,7 @@ def scramble_keypad_chooser():
def kill_key_chooser():
# kbtn = single keypress after anti-phishing words will wipe seed
s = SettingsObject()
s = SettingsObject.prelogin()
which = s.get('kbtn', -1)
del s
which = int(which) + 1
@ -94,7 +94,7 @@ def kill_key_chooser():
def set(idx, text):
# save it, but "outside" of login PIN
s = SettingsObject()
s = SettingsObject.prelogin()
if idx == 0:
s.remove_key('kbtn')
else:

View File

@ -33,7 +33,7 @@ def real_countdown_chooser(tag, offset, def_to):
ch = lgto_ch[offset:]
va = lgto_va[offset:]
s = SettingsObject()
s = SettingsObject.prelogin()
timeout = s.get(tag, def_to) # in minutes
try:
which = va.index(timeout)
@ -42,7 +42,7 @@ def real_countdown_chooser(tag, offset, def_to):
def set_it(idx, text):
# save on key0, not normal settings
s = SettingsObject()
s = SettingsObject.prelogin()
s.set(tag, va[idx])
s.save()
del s

View File

@ -329,7 +329,7 @@ NormalSystem = [
MenuItem('Type Passwords', f=password_entry,
predicate=lambda: settings.get("emu", False) and has_secrets()),
MenuItem('Seed Vault', menu=make_seed_vault_menu,
predicate=lambda: settings.get('seedvault') and has_secrets()),
predicate=lambda: settings.master_get('seedvault') and has_secrets()),
MenuItem('Secure Logout', f=logout_now),
MenuItem('Advanced/Tools', menu=AdvancedNormalMenu),
MenuItem('Settings', menu=SettingsMenu),

View File

@ -125,8 +125,6 @@ class OutptValueCache:
# memory management: can't store very much, so trim as needed
depth = HISTORY_SAVED
if settings.capacity > 0.8:
depth //= 2
# also limit in-memory use
cls.load_cache()

View File

@ -58,7 +58,8 @@ glob.numpad = numpad
# NV settings
from nvstore import SettingsObject
settings = SettingsObject(glob.dis)
settings = SettingsObject()
settings.load(glob.dis)
glob.settings = settings
async def more_setup():

View File

@ -78,6 +78,7 @@ from version import mk_num, is_devmode
KEEP_IF_BLANK_SETTINGS = ["bkpw", "wa", "sighshchk", "emu", "rz",
"axskip", "del", "pms", "idle_to", "b39skip"]
SEEDVAULT_FIELDS = [ 'seeds', 'seedvault', 'xfp' ]
NUM_SLOTS = const(100)
SLOTS = range(NUM_SLOTS)
@ -89,42 +90,25 @@ def MK4_FILENAME(slot):
return MK4_WORKDIR + ('%03x.aes' % slot)
# master current dict
master_sv_data = None
master_nvram_key = None
def extract_master_sv_data(settings_dict):
# allows us to specify what we want to keep
# in global 'master_sv_data' variable
# and save RAM
if settings_dict is None:
return
seeds = settings_dict.get("seeds", [])
seedvault = settings_dict.get("seedvault", 0)
if (not seedvault) and (not seeds):
return
return {"seeds": seeds, "seedvault": seedvault,
"xfp": settings_dict.get("xfp", 0)}
def set_master_sv_data(data, key):
global master_sv_data, master_nvram_key
master_sv_data = extract_master_sv_data(data)
master_nvram_key = key
class SettingsObject:
# class vars: track a few values from master seed settings
master_sv_data = {}
master_nvram_key = None
def __init__(self, dis=None):
def __init__(self, nvram_key=None):
# NOTE: constructor no longer loads the values by default (too slow).
self.is_dirty = 0
self.my_pos = None
self.nvram_key = b'\0'*32
self.capacity = 0
self.nvram_key = nvram_key or b'\0'*32
self.current = self.default_values()
self.load(dis)
@classmethod
def prelogin(cls):
# make an instance of the pre-login settings (ie. w/o key)
rv = cls()
rv.load()
return rv
def get_aes(self, pos):
# Build AES object for en/decrypt of specific block.
@ -159,7 +143,6 @@ class SettingsObject:
for round in range(5):
s.update('pad')
s = sha256(s.digest())
key = s.digest()
@ -167,7 +150,7 @@ class SettingsObject:
if mine:
blank_object(new_secret)
# for restore from backup case, or when changing (created) the seed
# save value for use in self.get_aes()
self.nvram_key = key
def get_capacity(self):
@ -272,6 +255,59 @@ class SettingsObject:
yield pos, taste
def leaving_master_seed(self):
# going from master seed to a tmp seed, so capture a few values we need.
SettingsObject.master_nvram_key = self.nvram_key
for fn in SEEDVAULT_FIELDS:
SettingsObject.master_sv_data[fn] = self.current.get(fn)
def return_to_master_seed(self):
# switching from a tmp seed to the normal master seed
# - we already kept the key needed, so just re-read
assert SettingsObject.master_nvram_key
self.nvram_key = SettingsObject.master_nvram_key
self.load()
# these value no longer required, and might become stale
SettingsObject.master_sv_data.clear()
SettingsObject.master_nvram_key = None
def master_set(self, key, value):
# Set a value, and it must be saved under the master seed's
# Concern is we may be changing a setting from a tmp seed mode
# - always does a save
from glob import settings as self
if not SettingsObject.master_nvram_key:
# simple, we are already on master seed
self.set(key, value)
self.save()
else:
# harder, slower: have to load, change and write
tmp = SettingsObject(nvram_key=SettingsObject.master_nvram_key)
tmp.load()
tmp.set(key, value)
tmp.save()
del tmp
# track our copies
if key in SEEDVAULT_FIELDS:
SettingsObject.master_sv_data[key] = value
def master_get(self, kn, default=None):
# Read a value from master seed's settings, perhaps from within context of tmp seed
from glob import settings as self
if not SettingsObject.master_nvram_key:
# simple, we are already on master seed
return self.get(kn, default)
# LIMITATION: only supporting a few values we know we will need
assert kn in SEEDVAULT_FIELDS
return SettingsObject.master_sv_data.get(kn, default)
def load(self, dis=None):
# Search all slots for any we can read, decrypt that,
# and pick the newest one (in unlikely case of dups)
@ -279,7 +315,6 @@ class SettingsObject:
self.current.clear()
self.my_pos = None
self.is_dirty = 0
self.capacity = 0
nonempty = set()
for pos, taste in self._nonempty_slots(dis):
@ -330,9 +365,6 @@ class SettingsObject:
self.current['chain'] = 'XTN'
def get(self, kn, default=None):
if master_sv_data and kn in ["seeds", "seedvault"]:
# we are in temporary mode as global 'master_sv_data' is populated
return master_sv_data.get(kn, default)
return self.current.get(kn, default)
def changed(self):
@ -459,7 +491,6 @@ class SettingsObject:
# act blank too, just in case.
self.current.clear()
self.is_dirty = 0
self.capacity = 0
@staticmethod
def default_values():

View File

@ -446,24 +446,22 @@ class PinAttempt:
with stash.SensitiveValues(raw_secret, bypass_tmp=bypass_tmp) as sv:
if chain is not None:
sv.chain = chain
if raw_secret is None:
# restore to main wallet
settings.nvram_key = nvstore.master_nvram_key
settings.load()
# blank global as we return to main seed
nvstore.set_master_sv_data(None, None)
# restore to main wallet's settings
settings.return_to_master_seed()
else:
sv.capture_xpub()
settings.merge_previous_active(old_values)
except stash.ZeroSecretException:
# secret is zero - using ephemeral secrets in CC
# with no se2 secret
settings.nvram_key = b'\0'*32
settings.load()
# set PA_ZEROS to 1
self.state_flags |= (1 << 4)
return
self.state_flags |= PA_ZERO_SECRET
settings.merge_previous_active(old_values)
def tmp_secret(self, encoded, chain=None, bip39pw=''):
# Use indicated secret and stop using the SE; operate like this until reboot
@ -473,11 +471,9 @@ class PinAttempt:
return False
if not self.tmp_value:
# going from master seed
import nvstore
# leaving from master seed, might capture some useful values
from glob import settings
nvstore.set_master_sv_data(settings.current,
settings.nvram_key)
settings.leaving_master_seed()
self.tmp_value = val
@ -487,6 +483,7 @@ class PinAttempt:
# Copies system settings to new encrypted-key value, calculates
# XFP, XPUB and saves into that, and starts using them.
self.new_main_secret(self.tmp_value, chain=chain, bip39pw=bip39pw)
return True
def trick_request(self, method_num, data):

View File

@ -23,6 +23,7 @@ from ubinascii import unhexlify as a2b_hex
from pwsave import PassphraseSaver
from glob import settings, dis
from pincodes import pa
from nvstore import SettingsObject
# seed words lengths we support: 24=>256 bits, and recommended
VALID_LENGTHS = (24, 18, 12)
@ -405,20 +406,22 @@ async def new_from_dice(nwords):
# send them to home menu, now with a wallet enabled
goto_top_menu(first_time=True)
async def in_seed_vault(xfp=None, seeds=None):
def in_seed_vault(xfp=None):
# Test if indicated xfp (or currently active XFP) is in the seed vault already.
if xfp is None:
xfp = xfp2str(settings.get("xfp", 0))
if seeds is None:
seeds = settings.get("seeds", [])
if xfp in [s[0] for s in seeds]:
seeds = settings.master_get("seeds", [])
if seeds and (xfp in [s[0] for s in seeds]):
return True
return False
async def add_seed_to_vault(encoded, meta=None):
import nvstore
if not settings.get("seedvault", False):
if not settings.master_get("seedvault", False):
# seed vault disabled
return
if pa.is_secret_blank():
@ -430,20 +433,16 @@ async def add_seed_to_vault(encoded, meta=None):
new_xfp_str = xfp2str(new_xfp)
# do not offer to store secrets that are already in vault
if await in_seed_vault(new_xfp_str, settings.get("seeds", [])):
if in_seed_vault(new_xfp_str):
return
# do not offer to store main seed
if nvstore.master_sv_data:
main_xfp = nvstore.master_sv_data.get("xfp", 0)
else:
main_xfp = settings.get("xfp", 0)
main_xfp = settings.master_get("xfp", 0)
if new_xfp == main_xfp:
return
# if in ephemeral 'seeds' are grabbed from master_sv_data global var
seeds = settings.get("seeds", [])
seeds = settings.master_get("seeds", [])
xfp_ui = "[%s]" % new_xfp_str
story = ("Press (1) to "
@ -452,29 +451,21 @@ async def add_seed_to_vault(encoded, meta=None):
"to continue without saving.")
ch = await ux_show_story(story, escape="1")
if ch == "1":
eph_nvram_key = None
seeds.append((new_xfp_str,
stash.SecretStash.storage_encode(encoded),
xfp_ui,
meta))
if nvstore.master_sv_data:
# in ephemeral
nvstore.master_sv_data["seeds"] = seeds
eph_nvram_key = settings.nvram_key[:]
settings.nvram_key = nvstore.master_nvram_key
settings.load()
if ch != "1":
# didn't want to save
return
settings.set("seeds", seeds)
settings.save()
# Save it into master settings
seeds.append((new_xfp_str,
stash.SecretStash.storage_serialize(encoded),
xfp_ui,
meta))
if eph_nvram_key:
# restore ephemerlal settings after save to main settings
settings.nvram_key = eph_nvram_key
settings.load()
settings.master_set("seeds", seeds)
await ux_show_story(xfp_ui + "\nSaved to Seed Vault")
return True
await ux_show_story(xfp_ui + "\nSaved to Seed Vault")
return True
async def set_ephemeral_seed(encoded, chain=None, summarize_ux=True, bip39pw='',
is_restore=False, meta=None):
@ -812,8 +803,7 @@ class SeedVaultMenu(MenuSystem):
goto_top_menu()
@staticmethod
async def _clear(menu, label, item):
import nvstore
async def _remove(menu, label, item):
from glob import dis, settings
idx, xfp_str, encoded = item.arg
@ -823,10 +813,9 @@ class SeedVaultMenu(MenuSystem):
"only remove from seed vault and keep "
"encrypted settings for later use.\n\n"
"WARNING: Funds will be lost if wallet is"
" not backed up elsewhere.")
" not backed-up elsewhere.")
ch = await ux_show_story(title="[" + xfp_str + "]",
msg=msg, escape="1")
ch = await ux_show_story(title="[" + xfp_str + "]", msg=msg, escape="1")
if ch == "x": return
dis.fullscreen("Saving...")
@ -843,46 +832,28 @@ class SeedVaultMenu(MenuSystem):
# slot wiping
if tmp_val:
# wipe current settings
master_nvram_key = nvstore.master_nvram_key
settings.blank()
pa.tmp_value = False
settings.return_to_master_seed()
else:
# in main settings
settings.save()
master_nvram_key = settings.nvram_key[:]
settings.set_key(pad_raw_secret(encoded))
settings.load()
settings.blank()
xs = SettingsObject()
xs.set_key(pad_raw_secret(encoded))
xs.load()
xs.blank()
del xs
# back to master settings
pa.tmp_value = False
settings.nvram_key = master_nvram_key
settings.load()
nvstore.set_master_sv_data(None, None)
eph_nvram_key = None
# will get global master_sv_data from nvstore if in ephemeral
seeds = settings.get("seeds", [])
# CAUTION: will get shadow copy if in tmp seed mode already
seeds = settings.master_get("seeds", [])
try:
del seeds[idx]
except IndexError:
pass
if nvstore.master_sv_data:
# in ephemeral
nvstore.master_sv_data["seeds"] = seeds
eph_nvram_key = settings.nvram_key[:]
settings.nvram_key = nvstore.master_nvram_key
settings.load()
# need to load and work on master secrets, will be slow if on tmp seed
settings.master_set("seeds", seeds)
settings.set("seeds", seeds)
settings.save()
if tmp_val and (not wipe_slot):
# we were in ephemeral mode before and have not
# wiped seed - return back to ephemeral
settings.nvram_key = eph_nvram_key
settings.load()
elif tmp_val and wipe_slot:
if tmp_val and wipe_slot:
goto_top_menu()
# pop menu stack
@ -893,28 +864,27 @@ class SeedVaultMenu(MenuSystem):
@staticmethod
async def _detail(menu, label, item):
xfp_str, encoded, name, meta = item.arg
# - first byte represents type of secret (internal encoding flag)
txt = SecretStash.summary(a2b_hex(encoded[0:2])[0])
detail = "Name:\n%s\n\nMaster XFP:\n%s\n\nMetadata:\n%s\n\nSecret Type:\n%s" % (
# (-2) one byte in hex that represents type of secret (internal)
name, xfp_str, meta, txt
)
detail = "Name:\n%s\n\nMaster XFP:\n%s\n\nOrigin:\n%s\n\nSecret Type:\n%s" \
% (name, xfp_str, meta, txt)
await ux_show_story(detail)
@staticmethod
async def _rename(menu, label, item):
# let them edit the name
import nvstore
from glob import dis
from ux import ux_input_text
idx, xfp_str = item.arg
# will get global master_sv_data from nvstore if in ephemeral
seeds = settings.get("seeds", [])
seeds = settings.master_get("seeds", [])
chk_xfp, encoded, old_name, meta = seeds[idx]
assert chk_xfp == xfp_str
from ux import ux_input_text
new_name = await ux_input_text(old_name, confirm_exit=False, max_len=40)
if not new_name:
@ -923,26 +893,20 @@ class SeedVaultMenu(MenuSystem):
dis.fullscreen("Saving...")
# save it
eph_nvram_key = None
seeds[idx] = (chk_xfp, encoded, new_name, meta)
if nvstore.master_sv_data:
# in ephemeral
nvstore.master_sv_data["seeds"] = seeds
eph_nvram_key = settings.nvram_key[:]
settings.nvram_key = nvstore.master_nvram_key
settings.load()
settings.set("seeds", seeds)
settings.save()
if eph_nvram_key:
# restore ephemerlal settings after save to main settings
settings.nvram_key = eph_nvram_key
settings.load()
# need to load and work on master secrets, will be slow if on tmp seed
settings.master_set("seeds", seeds)
# update label in sub-menu
menu.items[0].label = new_name
menu.items[0].arg = menu.items[0].arg[0:2] + (new_name,) + menu.items[0].arg[3:]
# .. and name in parent menu too
parent = the_ux.parent_of(menu)
if parent:
parent.update_contents()
@classmethod
def construct(cls):
# Dynamic menu with user-defined names of seeds shown
@ -951,31 +915,32 @@ class SeedVaultMenu(MenuSystem):
rv = []
seeds = settings.get("seeds", [])
seeds = settings.master_get("seeds", [])
cur_xfp = xfp2str(settings.get("xfp", 0))
if not seeds:
rv.append(MenuItem('(none saved yet)'))
rv.append(MenuItem("Temporary Seed", menu=make_ephemeral_seed_menu))
else:
for i, (xfp_str, encoded, name, meta) in enumerate(seeds):
current_active = cur_xfp == xfp_str
is_active = (cur_xfp == xfp_str)
submenu = [
MenuItem(name, f=cls._detail, arg=(xfp_str, encoded, name, meta)),
MenuItem('Use This Seed', f=cls._set, arg=(xfp_str, encoded)),
MenuItem('Rename', f=cls._rename, arg=(i, xfp_str)),
MenuItem('Delete', f=cls._clear, arg=(i, xfp_str, encoded)),
MenuItem('Delete', f=cls._remove, arg=(i, xfp_str, encoded)),
]
if current_active:
submenu[1] = MenuItem("In Use")
if is_active:
submenu[1] = MenuItem("Seed In Use")
submenu[1].is_chosen = lambda: True
if pa.tmp_value and (not current_active):
if pa.tmp_value and (not is_active):
# if different ephemeral wallet active
# DO NOT offer any modification api (rename/delete)
submenu = submenu[:2]
item = MenuItem(('%-4s' % (str(i+1)+":")) + ('[%s]' % xfp_str),
menu=MenuSystem(submenu))
if current_active:
item = MenuItem('%d: %s' % (i+1, name), menu=MenuSystem(submenu))
if is_active:
item.is_chosen = lambda: True
rv.append(item)
@ -1008,7 +973,7 @@ class EphemeralSeedMenu(MenuSystem):
@classmethod
def construct(cls):
from glob import NFC, settings
from glob import NFC
from actions import nfc_recv_ephemeral, import_tapsigner_backup_file, import_xprv
import_ephemeral_menu = [
@ -1028,14 +993,14 @@ class EphemeralSeedMenu(MenuSystem):
MenuItem("Generate Words", menu=gen_ephemeral_menu),
MenuItem("Import Words", menu=import_ephemeral_menu),
MenuItem("Import XPRV", f=import_xprv, arg=True), # ephemeral=True
MenuItem("Tapsigner Backup", f=import_tapsigner_backup_file, arg=True), # ephemeral=True
MenuItem("Tapsigner Backup", f=import_tapsigner_backup_file, arg=True), # ephemeral=True
]
return rv
async def make_ephemeral_seed_menu(*a):
if (not pa.tmp_value) and (not settings.get("seedvault", False)):
if (not pa.tmp_value) and (not settings.master_get("seedvault", False)):
# force a warning on them, unless they are already doing it.
ch = await ux_show_story(
"Temporary seed is a secret completely separate "

View File

@ -132,7 +132,8 @@ class SecretStash:
return 'master', ms, hd
@staticmethod
def storage_encode(secret):
def storage_serialize(secret):
# make it a JSON-compatible field
return B2A(bytes(secret).rstrip(b"\x00"))
@staticmethod

View File

@ -861,6 +861,17 @@ def settings_get(sim_exec):
return doit
@pytest.fixture()
def master_settings_get(sim_exec):
def doit(key):
cmd = f"RV.write(repr(settings.master_get('{key}')))"
resp = sim_exec(cmd)
assert 'Traceback' not in resp, resp
return eval(resp)
return doit
@pytest.fixture()
def settings_remove(sim_exec):

View File

@ -9,7 +9,8 @@ import stash
from seed import set_seed_value
from utils import xfp2str
from actions import goto_top_menu
import nvstore
from nvstore import SettingsObject
tn = chains.BitcoinTestnet
@ -22,8 +23,8 @@ settings.set('idle_to', 0)
import main
pa.tmp_value = None
nvstore.master_sv_data = None
nvstore.master_nvram_key = None
SettingsObject.master_sv_data = {}
SettingsObject.master_nvram_key = None
set_seed_value(main.WORDS)
print("New key in effect: %s" % settings.get('xpub', 'MISSING'))

View File

@ -218,8 +218,8 @@ def verify_ephemeral_secret_ui(cap_story, need_keypress, cap_menu, dev, fake_txn
pick_menu_item(sc_menu[0])
time.sleep(.1)
else:
assert "In Use" in m
pick_menu_item("In Use") # noop
assert "Seed In Use" in m
pick_menu_item("Seed In Use") # noop
# delete it from records
pick_menu_item("Delete")
@ -748,7 +748,7 @@ def test_activate_current_tmp_secret(reset_seed_words, goto_eph_seed_menu,
'017caa3142d48791f837b42fcd7a98662f9fb4101a15ae87cdbc1fecc96f33c11ffcefd8121daaba0625c918a335a0712b8c35c2da60e6fc6eef78b7028f4be02a',
None), # BIP-85 -> BIP-32 -> #23
])
def test_seed_vault_menus(dev, data, settings_set, settings_get, pick_menu_item, need_keypress, cap_story,
def test_seed_vault_menus(dev, data, settings_set, master_settings_get, pick_menu_item, need_keypress, cap_story,
cap_menu, reset_seed_words, get_identity_story, get_seed_value_ux, fake_txn,
try_sign, sim_exec, goto_home):
# Verify "seed vault" feature works as intended
@ -814,6 +814,7 @@ def test_seed_vault_menus(dev, data, settings_set, settings_get, pick_menu_item,
need_keypress("y")
m = cap_menu()
assert m[0] == "AAAA"
# UNTESTED: parent menu will also show our updated name
pick_menu_item("Use This Seed")
time.sleep(.1)
title, story = cap_story()
@ -849,7 +850,7 @@ def test_seed_vault_menus(dev, data, settings_set, settings_get, pick_menu_item,
assert encoded[0:len(stored_secret)] == stored_secret
# check rename worked
seeds = settings_get("seeds")
seeds = master_settings_get("seeds")
assert len(seeds) == 1
entry = seeds[0]
assert len(entry) == 4
@ -864,7 +865,7 @@ def test_seed_vault_menus(dev, data, settings_set, settings_get, pick_menu_item,
def test_seed_vault_captures(request, dev, settings_set, settings_get, pick_menu_item,
need_keypress, cap_story, reset_seed_words, fake_txn,
generate_ephemeral_words, goto_home, get_secrets,
generate_ephemeral_words, goto_home, get_secrets, master_settings_get,
import_ephemeral_xprv, set_bip39_pw, restore_main_seed,
restore_seed_xor, derive_bip85_secret, activate_bip85_ephemeral):
# Capture seeds by all the different paths and verify correct values are captured.
@ -928,7 +929,7 @@ def test_seed_vault_captures(request, dev, settings_set, settings_get, pick_menu
restore_main_seed(seed_vault=True)
# check all saved okay
seeds = settings_get('seeds')
seeds = master_settings_get('seeds')
n_seeds = len(seeds)
assert n_seeds == expect_count
@ -1041,7 +1042,7 @@ def test_seed_vault_modifications(settings_set, reset_seed_words, pick_menu_item
time.sleep(.1)
m = cap_menu()
assert "Rename" in m
assert "In Use" in m
assert "Seed In Use" in m
assert "Delete" in m
pick_menu_item("Rename")
@ -1084,7 +1085,7 @@ def test_seed_vault_modifications(settings_set, reset_seed_words, pick_menu_item
time.sleep(.1)
m = cap_menu()
assert "Rename" in m
assert "In Use" in m
assert "Seed In Use" in m
assert "Delete" in m
pick_menu_item("Delete")