Merge branch 'dev' into final_word_v2

This commit is contained in:
kdmukai
2022-06-15 14:21:32 -05:00
10 changed files with 102909 additions and 77 deletions
+8
View File
@@ -142,6 +142,14 @@ The Orange Pill enclosure design offers a more finished look that includes butto
The upper and lower portions of the enclosure can be printed using a standard FDM 3D printer, no supports necessary. The buttons and joystick nub should ideally be produced with a SLA/resin printer. An overview of the entire assembly process can be found [here](https://youtu.be/aIIc2DiZYcI). To access the design files and printable models, click [here](https://github.com/SeedSigner/seedsigner/tree/main/enclosures/orange_pill).
### Community Designs
* [Lil Pill](https://cults3d.com/en/3d-model/gadget/lil-pill-seedsigner-case) by @_CyberNomad
* [OrangeSurf Case](https://github.com/orangesurf/orangesurf-seedsigner-case) by @OrangeSurfBTC
* [PS4 Seedsigner](https://www.thingiverse.com/thing:5363525) by @Silexperience
* [OpenPill Faceplate](https://www.printables.com/en/model/179924-seedsigner-open-pill-cover-plates-digital-cross-jo) by @Revetuzo
* [Waveshare CoverPlate](https://cults3d.com/en/3d-model/various/seedsigner-coverplate-for-waveshare-1-3-inch-lcd-hat-with-240x240-pixel-display) by @Adathome1
---------------
# SeedQR Printable Templates
Binary file not shown.
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -1,4 +1,4 @@
embit==0.4.10
embit @ git+https://github.com/seedsigner/embit.git@03cba13e0add64b241972c67e2aa970cb2e3a5d2
numpy==1.21.1
picamera==1.13
Pillow==8.2.0
+8 -4
View File
@@ -118,8 +118,12 @@ class PSBTOverviewScreen(ButtonListScreen):
# max_destination_col_width += curve_width
# Now let's maximize the actual destination col by adjusting our addr truncation
def calculate_destination_col_width(truncate_at: int):
def calculate_destination_col_width(truncate_at: int = 0):
def truncate_destination_addr(addr):
# TODO: Properly handle the ellipsis truncation in different languages
if len(addr) <= truncate_at + len("..."):
# No point in truncating
return addr
return f"{addr[:truncate_at]}..."
destination_column = []
@@ -129,7 +133,7 @@ class PSBTOverviewScreen(ButtonListScreen):
destination_column.append(truncate_destination_addr(addr))
for i in range(0, self.num_self_transfer_outputs):
destination_column.append(f"self-transfer")
destination_column.append(truncate_destination_addr("self-transfer"))
else:
# destination_column.append(f"{len(self.destination_addresses)} recipients")
destination_column.append(f"recipient 1")
@@ -151,10 +155,10 @@ class PSBTOverviewScreen(ButtonListScreen):
if len(self.destination_addresses) + self.num_self_transfer_outputs > 3:
# We're not going to display any destination addrs so truncation doesn't matter
(destination_text_width, destination_column) = calculate_destination_col_width(truncate_at=0)
(destination_text_width, destination_column) = calculate_destination_col_width()
else:
# Steadliy widen out the destination column until we run out of space
for i in range(6, 13):
for i in range(6, 14):
(new_width, new_col_text) = calculate_destination_col_width(truncate_at=i)
if new_width > max_destination_col_width:
break
+4 -10
View File
@@ -451,7 +451,7 @@ class SeedOptionsScreen(ButtonListScreen):
@dataclass
class SeedWordsScreen(WarningEdgesMixin, ButtonListScreen):
seed: Seed = None
words: List[str] = None
page_index: int = 0
num_pages: int = 3
is_bottom_list: bool = True
@@ -459,15 +459,9 @@ class SeedWordsScreen(WarningEdgesMixin, ButtonListScreen):
def __post_init__(self):
self.title = f"Seed Words: {self.page_index+1}/{self.num_pages}"
super().__post_init__()
# Can only render 4 words per screen
words_per_page = 4
mnemonic = self.seed.mnemonic_display_list
# Slice the mnemonic to our current 4-word section
self.mnemonic = mnemonic[self.page_index*words_per_page:(self.page_index + 1)*words_per_page]
words_per_page = len(self.words)
self.body_x = 0
self.body_y = self.top_nav.height - int(GUIConstants.COMPONENT_PADDING / 2)
@@ -479,7 +473,7 @@ class SeedWordsScreen(WarningEdgesMixin, ButtonListScreen):
# Calc horizontal center based on longest word
max_word_width = 0
for word in self.mnemonic:
for word in self.words:
(left, top, right, bottom) = font.getbbox(word, anchor="ls")
if right > max_word_width:
max_word_width = right
@@ -503,7 +497,7 @@ class SeedWordsScreen(WarningEdgesMixin, ButtonListScreen):
)
draw = ImageDraw.Draw(self.body_img)
for index, word in enumerate(self.mnemonic):
for index, word in enumerate(self.words):
draw.rounded_rectangle(
(number_box_x, number_box_y, number_box_x + number_box_width, number_box_y + number_box_height),
fill="#202020",
+33 -19
View File
@@ -32,7 +32,8 @@ class PSBTSelectSeedView(View):
seeds = self.controller.storage.seeds
SCAN_SEED = ("Scan a seed", FontAwesomeIconConstants.QRCODE)
ENTER_WORDS = "Enter 12/24 words"
TYPE_12WORD = ("Enter 12-word seed", FontAwesomeIconConstants.KEYBOARD)
TYPE_24WORD = ("Enter 24-word seed", FontAwesomeIconConstants.KEYBOARD)
button_data = []
for seed in seeds:
button_str = seed.get_fingerprint(self.settings.get_value(SettingsConstants.SETTING__NETWORK))
@@ -45,7 +46,8 @@ class PSBTSelectSeedView(View):
pass
button_data.append((button_str, SeedSignerCustomIconConstants.FINGERPRINT, "blue"))
button_data.append(SCAN_SEED)
button_data.append(ENTER_WORDS)
button_data.append(TYPE_12WORD)
button_data.append(TYPE_24WORD)
selected_menu_num = ButtonListScreen(
title="Select Signer",
@@ -68,8 +70,12 @@ class PSBTSelectSeedView(View):
from seedsigner.views.scan_views import ScanView
return Destination(ScanView)
elif button_data[selected_menu_num] == ENTER_WORDS:
elif button_data[selected_menu_num] in [TYPE_12WORD, TYPE_24WORD]:
from seedsigner.views.seed_views import SeedMnemonicEntryView
if button_data[selected_menu_num] == TYPE_12WORD:
self.controller.storage.init_pending_mnemonic(num_words=12)
else:
self.controller.storage.init_pending_mnemonic(num_words=24)
return Destination(SeedMnemonicEntryView)
@@ -78,18 +84,22 @@ class PSBTOverviewView(View):
def __init__(self):
super().__init__()
# The PSBTParser takes a while to read the PSBT. Run the loading screen while we
# wait.
self.loading_screen = LoadingScreenThread(text="Parsing PSBT...")
self.loading_screen.start()
self.loading_screen = None
if not self.controller.psbt_parser or self.controller.psbt_parser.seed != self.controller.psbt_seed:
# Must run the PSBTParser or re-parse
self.controller.psbt_parser = PSBTParser(
self.controller.psbt,
seed=self.controller.psbt_seed,
network=self.settings.get_value(SettingsConstants.SETTING__NETWORK)
)
# The PSBTParser takes a while to read the PSBT. Run the loading screen while
# we wait.
self.loading_screen = LoadingScreenThread(text="Parsing PSBT...")
self.loading_screen.start()
try:
self.controller.psbt_parser = PSBTParser(
self.controller.psbt,
seed=self.controller.psbt_seed,
network=self.settings.get_value(SettingsConstants.SETTING__NETWORK)
)
except Exception as e:
self.loading_screen.stop()
raise e
def run(self):
@@ -126,7 +136,8 @@ class PSBTOverviewView(View):
)
# Everything is set. Stop the loading screen
self.loading_screen.stop()
if self.loading_screen:
self.loading_screen.stop()
# Run the overview screen
selected_menu_num = screen.display()
@@ -145,6 +156,8 @@ class PSBTOverviewView(View):
else:
return Destination(PSBTMathView)
class PSBTUnsupportedScriptTypeWarningView(View):
def run(self):
selected_menu_num = WarningScreen(
@@ -462,11 +475,12 @@ class PSBTFinalizeView(View):
loading_screen = LoadingScreenThread(text="Signing PSBT...")
loading_screen.start()
sig_cnt = PSBTParser.sig_count(psbt)
psbt.sign_with(psbt_parser.root)
trimmed_psbt = PSBTParser.trim(psbt)
loading_screen.stop()
try:
sig_cnt = PSBTParser.sig_count(psbt)
psbt.sign_with(psbt_parser.root)
trimmed_psbt = PSBTParser.trim(psbt)
finally:
loading_screen.stop()
if sig_cnt == PSBTParser.sig_count(trimmed_psbt):
# Signing failed / didn't do anything
+61 -43
View File
@@ -73,13 +73,13 @@ class SeedsMenuView(View):
class LoadSeedView(View):
def run(self):
SEED_QR = (" Scan a SeedQR", FontAwesomeIconConstants.QRCODE)
TYPE_24WORD = ("Enter 24-word seed", FontAwesomeIconConstants.KEYBOARD)
TYPE_12WORD = ("Enter 12-word seed", FontAwesomeIconConstants.KEYBOARD)
TYPE_24WORD = ("Enter 24-word seed", FontAwesomeIconConstants.KEYBOARD)
CREATE = (" Create a seed", FontAwesomeIconConstants.PLUS)
button_data=[
SEED_QR,
TYPE_24WORD,
TYPE_12WORD,
TYPE_24WORD,
CREATE,
]
@@ -96,14 +96,14 @@ class LoadSeedView(View):
from .scan_views import ScanView
return Destination(ScanView)
elif button_data[selected_menu_num] == TYPE_24WORD:
self.controller.storage.init_pending_mnemonic(num_words=24)
return Destination(SeedMnemonicEntryView)
elif button_data[selected_menu_num] == TYPE_12WORD:
self.controller.storage.init_pending_mnemonic(num_words=12)
return Destination(SeedMnemonicEntryView)
elif button_data[selected_menu_num] == TYPE_24WORD:
self.controller.storage.init_pending_mnemonic(num_words=24)
return Destination(SeedMnemonicEntryView)
elif button_data[selected_menu_num] == CREATE:
from .tools_views import ToolsMenuView
return Destination(ToolsMenuView)
@@ -647,46 +647,50 @@ class SeedExportXpubDetailsView(View):
self.loading_screen = LoadingScreenThread(text="Generating xpub...")
self.loading_screen.start()
if self.script_type == SettingsConstants.CUSTOM_DERIVATION:
derivation_path = self.custom_derivation
else:
derivation_path = PSBTParser.calc_derivation(
network=self.settings.get_value(SettingsConstants.SETTING__NETWORK),
wallet_type=self.sig_type,
script_type=self.script_type
)
try:
if self.script_type == SettingsConstants.CUSTOM_DERIVATION:
derivation_path = self.custom_derivation
else:
derivation_path = PSBTParser.calc_derivation(
network=self.settings.get_value(SettingsConstants.SETTING__NETWORK),
wallet_type=self.sig_type,
script_type=self.script_type
)
if self.settings.get_value(SettingsConstants.SETTING__XPUB_DETAILS) == SettingsConstants.OPTION__ENABLED:
embit_network = NETWORKS[SettingsConstants.map_network_to_embit(self.settings.get_value(SettingsConstants.SETTING__NETWORK))]
version = embit.bip32.detect_version(
derivation_path,
default="xpub",
network=embit_network
)
if self.settings.get_value(SettingsConstants.SETTING__XPUB_DETAILS) == SettingsConstants.OPTION__ENABLED:
embit_network = NETWORKS[SettingsConstants.map_network_to_embit(self.settings.get_value(SettingsConstants.SETTING__NETWORK))]
version = embit.bip32.detect_version(
derivation_path,
default="xpub",
network=embit_network
)
root = embit.bip32.HDKey.from_seed(
self.seed.seed_bytes,
version=embit_network["xprv"]
)
root = embit.bip32.HDKey.from_seed(
self.seed.seed_bytes,
version=embit_network["xprv"]
)
fingerprint = hexlify(root.child(0).fingerprint).decode('utf-8')
xprv = root.derive(derivation_path)
xpub = xprv.to_public()
xpub_base58 = xpub.to_string(version=version)
fingerprint = hexlify(root.child(0).fingerprint).decode('utf-8')
xprv = root.derive(derivation_path)
xpub = xprv.to_public()
xpub_base58 = xpub.to_string(version=version)
screen = seed_screens.SeedExportXpubDetailsScreen(
fingerprint=fingerprint,
has_passphrase=self.seed.passphrase is not None,
derivation_path=derivation_path,
xpub=xpub_base58,
)
screen = seed_screens.SeedExportXpubDetailsScreen(
fingerprint=fingerprint,
has_passphrase=self.seed.passphrase is not None,
derivation_path=derivation_path,
xpub=xpub_base58,
)
self.loading_screen.stop()
selected_menu_num = screen.display()
else:
selected_menu_num = 0
finally:
self.loading_screen.stop()
selected_menu_num = screen.display()
else:
self.loading_screen.stop()
selected_menu_num = 0
if selected_menu_num == 0:
return Destination(
@@ -792,6 +796,12 @@ class SeedWordsView(View):
NEXT = "Next"
DONE = "Done"
# Slice the mnemonic to our current 4-word section
words_per_page = 4 # TODO: eventually make this configurable for bigger screens?
mnemonic = self.seed.mnemonic_display_list
words = mnemonic[self.page_index*words_per_page:(self.page_index + 1)*words_per_page]
button_data = []
if self.page_index < self.num_pages - 1 or self.seed_num is None:
button_data.append(NEXT)
@@ -799,7 +809,8 @@ class SeedWordsView(View):
button_data.append(DONE)
selected_menu_num = seed_screens.SeedWordsScreen(
seed=self.seed,
title=f"Seed Words: {self.page_index+1}/{self.num_pages}",
words=words,
page_index=self.page_index,
num_pages=self.num_pages,
button_data=button_data,
@@ -1313,7 +1324,8 @@ class SeedSingleSigAddressVerificationSelectSeedView(View):
seeds = self.controller.storage.seeds
SCAN_SEED = ("Scan a seed", FontAwesomeIconConstants.QRCODE)
ENTER_WORDS = "Enter 12/24 words"
TYPE_12WORD = ("Enter 12-word seed", FontAwesomeIconConstants.KEYBOARD)
TYPE_24WORD = ("Enter 24-word seed", FontAwesomeIconConstants.KEYBOARD)
button_data = []
text = "Load the seed to verify"
@@ -1329,7 +1341,8 @@ class SeedSingleSigAddressVerificationSelectSeedView(View):
text = "Select seed to verify"
button_data.append(SCAN_SEED)
button_data.append(ENTER_WORDS)
button_data.append(TYPE_12WORD)
button_data.append(TYPE_24WORD)
selected_menu_num = seed_screens.SeedSingleSigAddressVerificationSelectSeedScreen(
title="Verify Address",
@@ -1356,7 +1369,12 @@ class SeedSingleSigAddressVerificationSelectSeedView(View):
from seedsigner.views.scan_views import ScanView
return Destination(ScanView)
elif button_data[selected_menu_num] == ENTER_WORDS:
elif button_data[selected_menu_num] in [TYPE_12WORD, TYPE_24WORD]:
from seedsigner.views.seed_views import SeedMnemonicEntryView
if button_data[selected_menu_num] == TYPE_12WORD:
self.controller.storage.init_pending_mnemonic(num_words=12)
else:
self.controller.storage.init_pending_mnemonic(num_words=24)
return Destination(SeedMnemonicEntryView)