Skip to content

Commit

Permalink
Merge pull request #518 from Foundation-Devices/SFT-1728-temporary-seeds
Browse files Browse the repository at this point in the history
SFT-1728: temporary seeds
  • Loading branch information
mjg-foundation authored Jul 30, 2024
2 parents e095fb6 + a88b855 commit 20e8711
Show file tree
Hide file tree
Showing 30 changed files with 549 additions and 88 deletions.
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

0 comments on commit 20e8711

Please sign in to comment.