Skip to content

Commit 09b3718

Browse files
authored
feat(core): misc features add (OneKeyHQ#286)
1. the passphrase input on device supports edit before commit. 2. mnemonics support edits if make mistake in input process 3. fingerprint unlock error tips in pin input screen
1 parent 29edc69 commit 09b3718

16 files changed

Lines changed: 294 additions & 102 deletions

File tree

core/src/apps/common/passphrase.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,8 @@ async def _request_on_host(ctx: wire.Context) -> str:
6464
if ack.passphrase:
6565
from trezor.ui.layouts import require_confirm_passphrase
6666

67-
await require_confirm_passphrase(ctx, ack.passphrase)
67+
if not await require_confirm_passphrase(ctx, ack.passphrase):
68+
raise wire.ActionCancelled("Passphrase cancelled")
6869

6970
return ack.passphrase
7071

core/src/apps/common/signverify.py

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import gc
12
from typing import TYPE_CHECKING
23
from ubinascii import hexlify
34

@@ -32,10 +33,22 @@ def is_non_printable(message: str) -> bool:
3233

3334

3435
def decode_message(message: bytes) -> str:
36+
message_len = len(message)
37+
38+
def to_hex(message: bytes) -> str:
39+
hex_message = hexlify(message).decode()
40+
if message_len > 1024:
41+
return hex_message
42+
else:
43+
return "0x" + hex_message
44+
3545
try:
36-
decoded_message = bytes(message).decode()
46+
if message_len > 1024:
47+
gc.collect()
48+
decoded_message = message.decode()
3749
if is_non_printable(decoded_message):
38-
return f"0x{hexlify(message).decode()}"
50+
return to_hex(message)
3951
return decoded_message
4052
except UnicodeError:
41-
return f"0x{hexlify(message).decode()}"
53+
gc.collect()
54+
return to_hex(message)

core/src/apps/management/recovery_device/homescreen.py

Lines changed: 40 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
from trezor.lvglui.i18n import gettext as _, keys as i18n_keys
1111
from trezor.messages import Success
1212
from trezor.ui.layouts import show_onekey_app_guide, show_popup, show_success
13+
from trezor.ui.layouts.lvgl.recovery import request_word
1314

1415
from apps.base import set_homescreen
1516
from apps.common import mnemonic
@@ -104,24 +105,26 @@ async def _continue_recovery_process(
104105
await _request_share_first_screen(ctx, word_count)
105106

106107
secret = None
108+
words = None
107109
while secret is None:
108-
if is_first_step:
109-
# If we are starting recovery, ask for word count first...
110-
if not word_count:
111-
word_count = await _request_word_count(ctx, dry_run)
112-
# ...and only then show the starting screen with word count.
113-
await _request_share_first_screen(ctx, word_count)
114-
assert word_count is not None
115-
116-
# ask for mnemonic words one by one
117-
try:
118-
words = await layout.request_mnemonic(ctx, word_count, backup_type)
119-
except wire.ActionCancelled:
120-
continue
121-
122-
# if they were invalid or some checks failed we continue and request them again
123110
if not words:
124-
continue
111+
if is_first_step:
112+
# If we are starting recovery, ask for word count first...
113+
if not word_count:
114+
word_count = await _request_word_count(ctx, dry_run)
115+
# ...and only then show the starting screen with word count.
116+
await _request_share_first_screen(ctx, word_count)
117+
assert word_count is not None
118+
119+
# ask for mnemonic words one by one
120+
try:
121+
words = await layout.request_mnemonic(ctx, word_count, backup_type)
122+
except wire.ActionCancelled:
123+
continue
124+
125+
# if they were invalid or some checks failed we continue and request them again
126+
if not words:
127+
continue
125128

126129
try:
127130
secret, backup_type = await _process_words(ctx, words)
@@ -130,7 +133,27 @@ async def _continue_recovery_process(
130133
# that the first step is complete.
131134
is_first_step = False
132135
except MnemonicError:
133-
await layout.show_invalid_mnemonic(ctx, word_count)
136+
words_list = words.split(" ")
137+
while True:
138+
result = await layout.show_invalid_mnemonic(ctx, words_list)
139+
if result is not None:
140+
assert word_count is not None
141+
try:
142+
word = await request_word(
143+
ctx,
144+
result,
145+
word_count,
146+
is_slip39=backup_types.is_slip39_word_count(word_count),
147+
)
148+
except wire.ActionCancelled:
149+
continue
150+
else:
151+
words_list[result] = word
152+
words = " ".join(words_list)
153+
break
154+
else:
155+
words = None
156+
break
134157

135158
assert backup_type is not None
136159
if dry_run:

core/src/apps/management/recovery_device/layout.py

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -153,18 +153,17 @@ async def show_dry_run_different_type(ctx: wire.GenericContext) -> None:
153153
)
154154

155155

156-
async def show_invalid_mnemonic(ctx: wire.GenericContext, word_count: int) -> None:
157-
if backup_types.is_slip39_word_count(word_count):
156+
async def show_invalid_mnemonic(
157+
ctx: wire.GenericContext, mnemonics: list[str]
158+
) -> None | int:
159+
if backup_types.is_slip39_word_count(len(mnemonics)):
158160
pass
159161
else:
160-
await show_warning(
161-
ctx,
162-
"warning_invalid_seed",
163-
_(i18n_keys.SUBTITLE__DEVICE_RECOVER_INVALID_RECOVERY_PHRASE),
164-
header=_(i18n_keys.TITLE__INVALID_RECOVERY_PHRASE),
165-
icon="A:/res/danger.png",
166-
btn_yes_bg_color=lv_colors.ONEKEY_BLACK,
167-
)
162+
from trezor.lvglui.scrs.recovery_device import InvalidMnemonic
163+
164+
screen = InvalidMnemonic(mnemonics)
165+
166+
return await ctx.wait(screen.request())
168167

169168

170169
async def show_share_already_added(ctx: wire.GenericContext) -> None:

core/src/apps/neo/get_address.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ async def get_address(
3333
ctx,
3434
address=address,
3535
address_n=path,
36-
network="Neo",
36+
network="Neo N3",
3737
)
3838

3939
return NeoAddress(address=address, public_key=pub_key_bytes)

core/src/apps/neo/helpers.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ def make_digest(raw_tx: bytes, network_magic: int = NETWORK_MAINNET) -> bytes:
4545

4646
def retrieve_network(network_magic: int) -> tuple[str, bool]:
4747
if is_mainnet(network_magic):
48-
return "Neo", True
48+
return "Neo N3", True
4949
elif is_testnet(network_magic):
5050
return "Neo Testnet", True
5151
else:

core/src/apps/sui/sign_message.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,13 @@ async def sign_message(
2424
address = sui_address_from_pubkey(pub_key_bytes)
2525

2626
len_bytes = uleb_encode(len(msg.message))
27-
intentMessage = PERSONALMESSAGE_INTENT_BYTES + len_bytes + msg.message
28-
27+
hasher = blake2b(outlen=32)
28+
hasher.update(PERSONALMESSAGE_INTENT_BYTES)
29+
hasher.update(len_bytes)
30+
hasher.update(msg.message)
2931
from trezor.ui.layouts import confirm_signverify
3032

3133
ctx.primary_color, ctx.icon_path = lv.color_hex(PRIMARY_COLOR), ICON
3234
await confirm_signverify(ctx, "Sui", decode_message(msg.message), address, False)
33-
34-
signature = ed25519.sign(
35-
node.private_key(), blake2b(data=intentMessage, outlen=32).digest()
36-
)
35+
signature = ed25519.sign(node.private_key(), hasher.digest())
3736
return SuiMessageSignature(signature=signature, address=address)

core/src/apps/sui/sign_tx.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import gc
2+
13
from trezor import wire
24
from trezor.crypto.curve import ed25519
35
from trezor.crypto.hashlib import blake2b
@@ -30,7 +32,7 @@ async def sign_tx(ctx: wire.Context, msg: SuiSignTx, keychain: Keychain) -> SuiS
3032

3133
data_total = msg.data_length
3234
data = bytearray()
33-
data += msg.data_initial_chunk
35+
data.extend(msg.data_initial_chunk)
3436
data_left = data_total - len(msg.data_initial_chunk)
3537

3638
hash_fn = blake2b(outlen=32)
@@ -39,10 +41,10 @@ async def sign_tx(ctx: wire.Context, msg: SuiSignTx, keychain: Keychain) -> SuiS
3941
resp = await send_request_chunk(ctx, data_left)
4042
data_left -= len(resp.data_chunk)
4143
hash_fn.update(resp.data_chunk)
42-
data += resp.data_chunk
44+
data.extend(resp.data_chunk)
4345

4446
hash = hash_fn.digest()
45-
await confirm_blind_sign_common(ctx, address, bytes(data))
47+
await confirm_blind_sign_common(ctx, address, data)
4648
else:
4749
intent = msg.raw_tx[:3]
4850
if INTENT_BYTES != intent:
@@ -57,6 +59,8 @@ async def sign_tx(ctx: wire.Context, msg: SuiSignTx, keychain: Keychain) -> SuiS
5759

5860

5961
async def send_request_chunk(ctx: wire.Context, data_left: int) -> SuiTxAck:
62+
gc.collect()
63+
6064
req = SuiTxRequest()
6165
if data_left <= 1024:
6266
req.data_length = data_left

core/src/trezor/lvglui/scrs/address.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,7 @@
318318
{
319319
"msg_type": MessageType.NeoGetAddress,
320320
"symbol": " NEO",
321-
"name": "Neo",
321+
"name": "Neo N3",
322322
"msg_class": "NeoGetAddress",
323323
"index_pos": -1,
324324
"base_path": [0x80000000 + 44, 0x80000000 + 888, 0x80000000 + 0, 0, 0],

core/src/trezor/lvglui/scrs/components/button.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,15 @@ def enable(
7070
self.add_style(StyleWrapper().bg_color(bg_color).text_color(text_color), 0)
7171
self.add_flag(lv.btn.FLAG.CLICKABLE)
7272

73+
def enable_no_bg_mode(self):
74+
self.add_style(StyleWrapper().bg_color(lv_colors.BLACK), 0)
75+
self.add_style(
76+
StyleWrapper().bg_color(lv_colors.ONEKEY_BLACK).bg_opa(),
77+
lv.PART.MAIN | lv.STATE.PRESSED,
78+
)
79+
self.clear_flag(lv.obj.FLAG.CLICKABLE)
80+
self.click_mask.add_flag(lv.obj.FLAG.CLICKABLE)
81+
7382

7483
class ListItemBtn(lv.btn):
7584
def __init__(

0 commit comments

Comments
 (0)