Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SFT-1728: temporary seeds #518

Merged
merged 28 commits into from
Jul 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
ad9d177
SFT-1728: starting with temporary settings mode
mjg-foundation Apr 5, 2024
8ac3e31
SFT-1728: fixed copying and added device settings exception
mjg-foundation Apr 5, 2024
a832451
SFT-1728: importing temporary seed working
mjg-foundation Apr 5, 2024
11184e4
SFT-1728: temporarily restored from backups
mjg-foundation Apr 5, 2024
f5c9070
SFT-1728: accounted for device settings
mjg-foundation Apr 8, 2024
5ede413
SFT-1728: entering temporary seed after permanent setup
mjg-foundation Apr 9, 2024
c1f346a
SFT-1728: entering temporary mode from key manager, still needs UI work
mjg-foundation Apr 9, 2024
e5b79c0
SFT-1728: fixed simulator in temporary mode, improved temporary mode UI
mjg-foundation Apr 10, 2024
d14e9a2
SFT-1728: moved temporary functionality into temporary_seed_flow
mjg-foundation Apr 12, 2024
ca6b8c1
SFT-1728: incorporated comments and ui improvements
mjg-foundation Apr 18, 2024
d08d6a6
SFT-1728: improved temporary seed question
mjg-foundation May 20, 2024
166c109
SFT-1728: removed spinner when clearing temporary seed
mjg-foundation Jun 21, 2024
41a5775
SFT-1728: removed old TODOs
mjg-foundation Jul 4, 2024
f8e9a7d
SFT-1728: first pass of hourglass icons, removed prints
mjg-foundation Jul 15, 2024
58c1b94
SFT-1728: prevented erasing from temporary mode, fixed normal erasing…
mjg-foundation Jul 16, 2024
35102f0
SFT-1728: hid restore backup in temporary mode, fixed backup code for…
mjg-foundation Jul 16, 2024
b67eb9f
SFT-1728: prevented saving nostr keys as temporary seed
mjg-foundation Jul 16, 2024
51f906b
SFT-1728: fixing wording and capitalization
mjg-foundation Jul 16, 2024
c84445b
SFT-1728: avoided scrollbar in key item menu
mjg-foundation Jul 17, 2024
f6f67e9
SFT-1728: another iteration of hourglass icons
mjg-foundation Jul 17, 2024
4d07332
SFT-1728: improved mono background for hourglass icon
mjg-foundation Jul 18, 2024
b263378
SFT-1728: manually edited hourglass background code to increase its v…
mjg-foundation Jul 18, 2024
8c76984
SFT-1728: finalized hourglass mono background
mjg-foundation Jul 22, 2024
d7f9975
SFT-1728: ensured initial seeds can be temporary, removed print
mjg-foundation Jul 22, 2024
77bfe63
SFT-1728: fixed import header and added cancel button to initial backup
mjg-foundation Jul 23, 2024
81ef57d
SFT-1728: removed unnecessary changes, fixed some copy, used hourglass
mjg-foundation Jul 23, 2024
ed8702a
SFT-1728: fixed account index out of bounds when switching keys
mjg-foundation Jul 26, 2024
a88b855
SFT-1728: temporary seeds entered from plus menu return to plus menu
mjg-foundation Jul 30, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 55 additions & 0 deletions ports/stm32/boards/Passport/images/color/ICON_HOURGLASS.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// SPDX-FileCopyrightText: © 2024 Foundation Devices, Inc. <[email protected]>
// SPDX-License-Identifier: GPL-3.0-or-later
//

#ifdef LV_LVGL_H_INCLUDE_SIMPLE
#include "lvgl.h"
#else
#include "lvgl/lvgl.h"
#endif

#ifndef LV_ATTRIBUTE_MEM_ALIGN
#define LV_ATTRIBUTE_MEM_ALIGN
#endif

#ifndef LV_ATTRIBUTE_IMG_ICON_HOURGLASS
#define LV_ATTRIBUTE_IMG_ICON_HOURGLASS
#endif

const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST LV_ATTRIBUTE_IMG_ICON_HOURGLASS uint8_t ICON_HOURGLASS_map[] = {
0x00, 0x00, 0x00, 0x00, /*Color of index 0*/
0xfe, 0xfe, 0xfe, 0xff, /*Color of index 1*/
0x00, 0x00, 0x00, 0x00, /*Color of index 2*/
0x00, 0x00, 0x00, 0x00, /*Color of index 3*/

0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00,
0x05, 0x55, 0x55, 0x55, 0x50,
0x01, 0x15, 0x55, 0x54, 0x40,
0x01, 0x05, 0x55, 0x50, 0x40,
0x01, 0x41, 0x55, 0x41, 0x40,
0x00, 0x50, 0x00, 0x05, 0x00,
0x00, 0x14, 0x14, 0x14, 0x00,
0x00, 0x05, 0x00, 0x50, 0x00,
0x00, 0x01, 0x41, 0x40, 0x00,
0x00, 0x01, 0x41, 0x40, 0x00,
0x00, 0x05, 0x00, 0x50, 0x00,
0x00, 0x14, 0x14, 0x14, 0x00,
0x00, 0x50, 0x55, 0x05, 0x00,
0x01, 0x41, 0x55, 0x41, 0x40,
0x01, 0x05, 0x55, 0x50, 0x40,
0x01, 0x15, 0x55, 0x54, 0x40,
0x05, 0x55, 0x55, 0x55, 0x50,
0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00,
};

const lv_img_dsc_t ICON_HOURGLASS = {
.header.cf = LV_IMG_CF_INDEXED_2BIT,
.header.always_zero = 0,
.header.reserved = 0,
.header.w = 20,
.header.h = 20,
.data_size = 116,
.data = ICON_HOURGLASS_map,
};
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions ports/stm32/boards/Passport/images/images.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ extern const lv_img_dsc_t ICON_FORWARD;
extern const lv_img_dsc_t ICON_HAMBURGER;
extern const lv_img_dsc_t ICON_HEALTH_CHECK;
extern const lv_img_dsc_t ICON_HOME;
extern const lv_img_dsc_t ICON_HOURGLASS;
extern const lv_img_dsc_t ICON_INFO;
extern const lv_img_dsc_t ICON_INPUT_MODE_LOWER_ALPHA;
extern const lv_img_dsc_t ICON_INPUT_MODE_NUMERIC;
Expand Down Expand Up @@ -130,6 +131,8 @@ extern const lv_img_dsc_t ICON_HEALTH_CHECK_BACKGROUND;
extern const lv_img_dsc_t ICON_HEALTH_CHECK;
extern const lv_img_dsc_t ICON_HOME_BACKGROUND;
extern const lv_img_dsc_t ICON_HOME;
extern const lv_img_dsc_t ICON_HOURGLASS_BACKGROUND;
extern const lv_img_dsc_t ICON_HOURGLASS;
extern const lv_img_dsc_t ICON_INFO_BACKGROUND;
extern const lv_img_dsc_t ICON_INFO;
extern const lv_img_dsc_t ICON_INPUT_MODE_LOWER_ALPHA;
Expand Down
52 changes: 52 additions & 0 deletions ports/stm32/boards/Passport/images/mono/ICON_HOURGLASS.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// SPDX-FileCopyrightText: © 2022 Foundation Devices, Inc. <[email protected]>
// SPDX-License-Identifier: GPL-3.0-or-later
//

#ifdef LV_LVGL_H_INCLUDE_SIMPLE
#include "lvgl.h"
#else
#include "lvgl/lvgl.h"
#endif
#ifndef LV_ATTRIBUTE_MEM_ALIGN
#define LV_ATTRIBUTE_MEM_ALIGN
#endif

#ifndef LV_ATTRIBUTE_IMG_ICON_HOURGLASS
#define LV_ATTRIBUTE_IMG_ICON_HOURGLASS
#endif

const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_IMG_ICON_HOURGLASS uint8_t ICON_HOURGLASS_map[] = {
0x00, 0x00, 0x00, 0x00, /*Color of index 0*/
0xfe, 0xfe, 0xfe, 0xff, /*Color of index 1*/

0x00, 0x00, 0x00,
0x00, 0x00, 0x00,
0x3f, 0xff, 0xc0,
0x17, 0xfe, 0x80,
0x13, 0xfc, 0x80,
0x19, 0xf9, 0x80,
0x0c, 0x03, 0x00,
0x06, 0x66, 0x00,
0x03, 0x0c, 0x00,
0x01, 0x98, 0x00,
0x01, 0x98, 0x00,
0x03, 0x0c, 0x00,
0x06, 0x66, 0x00,
0x0c, 0xf3, 0x00,
0x19, 0xf9, 0x80,
0x13, 0xfc, 0x80,
0x17, 0xfe, 0x80,
0x3f, 0xff, 0xc0,
0x00, 0x00, 0x00,
0x00, 0x00, 0x00,
};

const lv_img_dsc_t ICON_HOURGLASS = {
.header.cf = LV_IMG_CF_INDEXED_1BIT,
.header.always_zero = 0,
.header.reserved = 0,
.header.w = 20,
.header.h = 20,
.data_size = 68,
.data = ICON_HOURGLASS_map,
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// SPDX-FileCopyrightText: © 2024 Foundation Devices, Inc. <[email protected]>
// SPDX-License-Identifier: GPL-3.0-or-later
//

#ifdef LV_LVGL_H_INCLUDE_SIMPLE
#include "lvgl.h"
#else
#include "lvgl/lvgl.h"
#endif
#ifndef LV_ATTRIBUTE_MEM_ALIGN
#define LV_ATTRIBUTE_MEM_ALIGN
#endif

#ifndef LV_ATTRIBUTE_IMG_ICON_HOURGLASS_BACKGROUND
#define LV_ATTRIBUTE_IMG_ICON_HOURGLASS_BACKGROUND
#endif

const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_IMG_ICON_HOURGLASS_BACKGROUND uint8_t ICON_HOURGLASS_BACKGROUND_map[] = {
0x00, 0x00, 0x00, 0x00, /*Color of index 0*/
0xff, 0xff, 0xff, 0xff, /*Color of index 1*/

0x00, 0x00, 0x00,
0x00, 0x00, 0x00,
0x3f, 0xff, 0xf0,
0x3f, 0xff, 0xf0,
0x3f, 0xff, 0xf0,
0x1f, 0xff, 0xe0,
0x1f, 0xff, 0xe0,
0x1f, 0xff, 0xe0,
0x0f, 0xff, 0xc0,
0x07, 0xff, 0x80,
0x03, 0xff, 0x00,
0x03, 0xff, 0x00,
0x07, 0xff, 0x80,
0x0f, 0xff, 0xc0,
0x1f, 0xff, 0xe0,
0x1f, 0xff, 0xe0,
0x1f, 0xff, 0xe0,
0x3f, 0xff, 0xf0,
0x3f, 0xff, 0xf0,
0x3f, 0xff, 0xf0,
0x00, 0x00, 0x00,
0x00, 0x00, 0x00,
};

const lv_img_dsc_t ICON_HOURGLASS_BACKGROUND = {
.header.cf = LV_IMG_CF_INDEXED_1BIT,
.header.always_zero = 0,
.header.reserved = 0,
.header.w = 22,
.header.h = 22,
.data_size = 74,
.data = ICON_HOURGLASS_BACKGROUND_map,
};
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions ports/stm32/boards/Passport/manifest.py
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@
'flows/sign_psbt_microsd_flow.py',
'flows/sign_psbt_qr_flow.py',
'flows/sign_text_file_flow.py',
'flows/temporary_seed_flow.py',
'flows/terms_of_use_flow.py',
'flows/update_firmware_flow.py',
'flows/verify_address_flow.py',
Expand Down
7 changes: 6 additions & 1 deletion ports/stm32/boards/Passport/modules/export.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,12 @@ def ADD(key, val):

# user preferences - sort so that accounts is processed before multisig
multisig_ids = []
for k, v in sorted(settings.current.items()):
settings_dict = None
if settings.temporary_mode:
settings_dict = settings.temporary_settings
else:
settings_dict = settings.current
for k, v in sorted(settings_dict.items()):
# print('render handling key "{}"'.format(k))
if k[0] == '_':
continue # debug stuff in simulator
Expand Down
112 changes: 90 additions & 22 deletions ports/stm32/boards/Passport/modules/ext_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
from utils import to_str, call_later_ms
from constants import SPI_FLASH_SECTOR_SIZE
from passport import mem
from public_constants import DEVICE_SETTINGS


class ExtSettings:
Expand All @@ -45,6 +46,9 @@ def __init__(self, slots=None, slot_size=0, loop=None, name=None):
self.current = self.default_values()
self.overrides = {} # volatile overide values
self.last_save_slots = [-1, -1]
self.temporary_mode = False
self.temporary_settings = {}
self.temporary_overrides = {}

# NOTE: We don't load the settings initially since we don't have the AES key until
# the user logs in successfully.
Expand Down Expand Up @@ -206,13 +210,13 @@ def load(self):
sf.write(pos + i, h)

def get(self, kn, default=None):
if kn in self.overrides:
return self.overrides.get(kn)
if self.in_overrides(kn):
return self.get_from_overrides(kn, default)
else:
# Special case for xfp and xpub -- make sure they exist and create if not
if kn not in self.current:
if kn == 'root_xfp' and 'xfp' in self.current:
return self.current.get('xfp', default)
if not self.in_current(kn):
if kn == 'root_xfp' and self.in_current('xfp'):
return self.get_from_current('xfp', default)
if kn == 'xfp' or kn == 'xpub' or kn == 'root_xfp':
try:
# Update xpub/xfp in settings after creating new wallet
Expand All @@ -229,37 +233,74 @@ def get(self, kn, default=None):
finally:
# system.hide_busy_bar()
# These are overrides, so return them from there
return self.overrides.get(kn)
return self.get_from_overrides(kn, default)

return self.current.get(kn, default)
return self.get_from_current(kn, default)

def changed(self):
self.is_dirty += 1
if self.is_dirty < 2 and self.loop:
call_later_ms(250, self.write_out())

def set(self, kn, v):
def set(self, kn, v, permanent=False):
# print('set({}, {}'.format(kn, v))
self.current[kn] = v
self.changed()
if (not self.temporary_mode or kn in DEVICE_SETTINGS) or permanent:
self.current[kn] = v
self.changed()
return
self.temporary_settings[kn] = v

def get_from_current(self, kn, default):
if not self.temporary_mode or kn in DEVICE_SETTINGS:
return self.current.get(kn, default)
return self.temporary_settings.get(kn, default)

def get_from_overrides(self, kn, default):
if not self.temporary_mode or kn in DEVICE_SETTINGS:
return self.overrides.get(kn, default)
return self.temporary_overrides.get(kn, default)

def set_volatile(self, kn, v):
self.overrides[kn] = v
if not self.temporary_mode or kn in DEVICE_SETTINGS:
self.overrides[kn] = v
return
self.temporary_overrides[kn] = v

def in_current(self, kn):
if not self.temporary_mode or kn in DEVICE_SETTINGS:
return kn in self.current
return kn in self.temporary_settings

def in_overrides(self, kn):
if not self.temporary_mode or kn in DEVICE_SETTINGS:
return kn in self.overrides
return kn in self.temporary_overrides

def clear_volatile(self, kn):
if kn in self.overrides:
del self.overrides[kn]
if not self.temporary_mode or kn in DEVICE_SETTINGS:
if kn in self.overrides:
del self.overrides[kn]
return
if kn in self.temporary_overrides:
del self.temporary_overrides[kn]

def remove(self, kn):
# print('remove(\'{}\') called!'.format(kn))
if kn in self.current:
self.current.pop(kn, None)
self.changed()
if self.in_current(kn):
if not self.temporary_mode or kn in DEVICE_SETTINGS:
self.current.pop(kn, None)
self.changed()
return
self.temporary_settings.pop(kn, None)

def remove_regex(self, pattern):
import re
pattern = re.compile(pattern)
matches = [k for k in self.current if pattern.search(k)]
matches = []
if self.temporary_mode:
matches = [k for k in self.temporary_settings if pattern.search(k)]
else:
matches = [k for k in self.current if pattern.search(k)]
for k in matches:
self.remove(k)

Expand All @@ -268,9 +309,14 @@ def clear(self):
# could be just:
# self.current = {}
# but accomodating the simulator here
rk = [k for k in self.current if k[0] != '_']
for k in rk:
del self.current[k]
if self.temporary_mode:
rk = [k for k in self.temporary_settings if k[0] != '_']
for k in rk:
del self.temporary_settings[k]
else:
rk = [k for k in self.current if k[0] != '_']
for k in rk:
del self.current[k]

self.changed()

Expand All @@ -295,7 +341,7 @@ async def write_out(self):
# Was sometimes running low on memory in this area: recover
try:
gc.collect()
self.save()
self.internal_save()
except MemoryError:
call_later_ms(250, self.write_out())

Expand Down Expand Up @@ -338,15 +384,23 @@ def erase_cache_entry(self, start_pos):
sf.wait_done()

def erase_all(self):
if self.temporary_mode:
return

for pos in self.slots:
self.erase_cache_entry(pos)
self.blank()

def save(self):
def internal_save(self):
# Make two saves in case one is corrupted
self.do_save(erase_old_pos=True)
self.do_save(erase_old_pos=False)

def save(self, permanent=False):
if self.temporary_mode and not permanent:
return
self.internal_save()

def do_save(self, erase_old_pos=True):
# print('do_save({})'.format(erase_old_pos))
# render as JSON, encrypt and write it.
Expand Down Expand Up @@ -426,6 +480,20 @@ def blank(self):
self.current.clear()
self.is_dirty = 0

def enter_temporary_mode(self):

# Avoid resetting temporary settings if already in temporary mode
if self.temporary_mode:
return

self.temporary_mode = True
self.temporary_settings = self.default_values()

def exit_temporary_mode(self):
self.temporary_mode = False
self.temporary_settings = {}
self.temporary_overrides = {}

@staticmethod
def default_values():
# Please try to avoid defaults here... It's better to put into code
Expand Down
Loading