refactor(core): improve build-time option for old/new UI

[no changelog]
mmilata/tt-pin-keyboard
Martin Milata 2 years ago
parent b64c69c3ff
commit f2b8822d76

@ -24,6 +24,7 @@ BITCOIN_ONLY ?= 0
TREZOR_MODEL ?= T
TREZOR_MEMPERF ?= 0
ADDRESS_SANITIZER ?= 0
UI2 ?= 0
OPENOCD_INTERFACE ?= stlink # -or- ftdi/olimex-arm-usb-tiny-h
OPENOCD_TRANSPORT ?= hla_swd # -or- jtag
@ -150,16 +151,16 @@ build_reflash: ## build reflash firmware + reflash image
dd if=build/bootloader/bootloader.bin of=$(REFLASH_BUILD_DIR)/sdimage.bin bs=1 seek=49152
build_firmware: templates build_cross ## build firmware with frozen modules
$(SCONS) CFLAGS="$(CFLAGS)" PRODUCTION="$(PRODUCTION)" TREZOR_MODEL="$(TREZOR_MODEL)" PYOPT="$(PYOPT)" BITCOIN_ONLY="$(BITCOIN_ONLY)" $(FIRMWARE_BUILD_DIR)/firmware.bin
$(SCONS) CFLAGS="$(CFLAGS)" PRODUCTION="$(PRODUCTION)" TREZOR_MODEL="$(TREZOR_MODEL)" PYOPT="$(PYOPT)" BITCOIN_ONLY="$(BITCOIN_ONLY)" UI2="$(UI2)" $(FIRMWARE_BUILD_DIR)/firmware.bin
build_unix: templates ## build unix port
$(SCONS) CFLAGS="$(CFLAGS)" $(UNIX_BUILD_DIR)/trezor-emu-core $(UNIX_PORT_OPTS) TREZOR_MODEL="$(TREZOR_MODEL)" BITCOIN_ONLY="$(BITCOIN_ONLY)" TREZOR_EMULATOR_ASAN="$(ADDRESS_SANITIZER)"
$(SCONS) CFLAGS="$(CFLAGS)" $(UNIX_BUILD_DIR)/trezor-emu-core $(UNIX_PORT_OPTS) TREZOR_MODEL="$(TREZOR_MODEL)" BITCOIN_ONLY="$(BITCOIN_ONLY)" TREZOR_EMULATOR_ASAN="$(ADDRESS_SANITIZER)" UI2="$(UI2)"
build_unix_frozen: templates build_cross ## build unix port with frozen modules
$(SCONS) CFLAGS="$(CFLAGS)" $(UNIX_BUILD_DIR)/trezor-emu-core $(UNIX_PORT_OPTS) TREZOR_MODEL="$(TREZOR_MODEL)" PYOPT="$(PYOPT)" BITCOIN_ONLY="$(BITCOIN_ONLY)" TREZOR_EMULATOR_ASAN="$(ADDRESS_SANITIZER)" TREZOR_MEMPERF="$(TREZOR_MEMPERF)" TREZOR_EMULATOR_FROZEN=1
$(SCONS) CFLAGS="$(CFLAGS)" $(UNIX_BUILD_DIR)/trezor-emu-core $(UNIX_PORT_OPTS) TREZOR_MODEL="$(TREZOR_MODEL)" PYOPT="$(PYOPT)" BITCOIN_ONLY="$(BITCOIN_ONLY)" TREZOR_EMULATOR_ASAN="$(ADDRESS_SANITIZER)" UI2="$(UI2)" TREZOR_MEMPERF="$(TREZOR_MEMPERF)" TREZOR_EMULATOR_FROZEN=1
build_unix_debug: templates ## build unix port
$(SCONS) --max-drift=1 CFLAGS="$(CFLAGS)" $(UNIX_BUILD_DIR)/trezor-emu-core $(UNIX_PORT_OPTS) TREZOR_MODEL="$(TREZOR_MODEL)" BITCOIN_ONLY="$(BITCOIN_ONLY)" TREZOR_EMULATOR_ASAN=1 TREZOR_EMULATOR_DEBUGGABLE=1
$(SCONS) --max-drift=1 CFLAGS="$(CFLAGS)" $(UNIX_BUILD_DIR)/trezor-emu-core $(UNIX_PORT_OPTS) TREZOR_MODEL="$(TREZOR_MODEL)" BITCOIN_ONLY="$(BITCOIN_ONLY)" TREZOR_EMULATOR_ASAN=1 UI2="$(UI2)" TREZOR_EMULATOR_DEBUGGABLE=1
build_cross: ## build mpy-cross port
$(MAKE) -C vendor/micropython/mpy-cross $(CROSS_PORT_OPTS)

@ -6,7 +6,7 @@ import os
BITCOIN_ONLY = ARGUMENTS.get('BITCOIN_ONLY', '0')
EVERYTHING = BITCOIN_ONLY != '1'
TREZOR_MODEL = ARGUMENTS.get('TREZOR_MODEL', 'T')
NEW_UI = TREZOR_MODEL == '1' or os.environ.get('NEW_UI', '0') == '1'
UI2 = ARGUMENTS.get('UI2', '0') == '1' or TREZOR_MODEL == '1'
FEATURE_FLAGS = {
"RDI": True,
@ -181,9 +181,10 @@ SOURCE_MOD += [
'vendor/micropython/lib/uzlib/crc32.c',
'vendor/micropython/lib/uzlib/tinflate.c',
]
if NEW_UI:
if UI2:
CPPDEFINES_MOD += [
'TREZOR_FONT_MEDIUM_ENABLE',
'TREZOR_UI2',
]
SOURCE_MOD += [
'embed/extmod/modtrezorui/font_tthoves_bold_16.c',
@ -200,7 +201,7 @@ SOURCE_MOD += [
SOURCE_MOD += [
'embed/extmod/rustmods/modtrezorproto.c',
]
if NEW_UI:
if UI2:
SOURCE_MOD += [
'embed/extmod/rustmods/modtrezorui2.c',
]
@ -555,7 +556,14 @@ if FROZEN:
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/ui/constants/__init__.py'))
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/ui/layouts/__init__.py'))
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/ui/layouts/common.py'))
if TREZOR_MODEL == 'T':
if TREZOR_MODEL == 'T' and UI2:
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/ui/components/tt/*.py'))
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/ui/constants/tt.py'))
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/ui/layouts/tt_v2/__init__.py'))
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/ui/layouts/tt/__init__.py'))
if EVERYTHING:
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/ui/layouts/tt/webauthn.py'))
elif TREZOR_MODEL == 'T':
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/ui/components/tt/*.py'))
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/ui/constants/tt.py'))
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/ui/layouts/tt/__init__.py'))
@ -716,7 +724,7 @@ def cargo_build():
features = ["model_tt"]
if BITCOIN_ONLY == "1":
features.append("bitcoin_only")
if NEW_UI:
if UI2:
features.append("ui")
if PYOPT == "0":
features.append("ui_debug")

@ -6,7 +6,7 @@ import os
BITCOIN_ONLY = ARGUMENTS.get('BITCOIN_ONLY', '0')
EVERYTHING = BITCOIN_ONLY != '1'
TREZOR_MODEL = ARGUMENTS.get('TREZOR_MODEL', 'T')
NEW_UI = TREZOR_MODEL == '1' or ARGUMENTS.get('NEW_UI', '0') == '1'
UI2 = ARGUMENTS.get('UI2', '0') == '1' or TREZOR_MODEL == '1'
FEATURE_FLAGS = {
"SECP256K1_ZKP": True,
@ -176,9 +176,10 @@ SOURCE_MOD += [
'vendor/micropython/lib/uzlib/crc32.c',
'vendor/micropython/lib/uzlib/tinflate.c',
]
if NEW_UI:
if UI2:
CPPDEFINES_MOD += [
'TREZOR_FONT_MEDIUM_ENABLE',
'TREZOR_UI2',
]
SOURCE_MOD += [
'embed/extmod/modtrezorui/font_tthoves_bold_16.c',
@ -197,7 +198,7 @@ SOURCE_MOD += [
SOURCE_MOD += [
'embed/extmod/rustmods/modtrezorproto.c',
]
if NEW_UI:
if UI2:
SOURCE_MOD += [
'embed/extmod/rustmods/modtrezorui2.c',
]
@ -516,7 +517,14 @@ if FROZEN:
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/ui/constants/__init__.py'))
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/ui/layouts/__init__.py'))
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/ui/layouts/common.py'))
if TREZOR_MODEL == 'T':
if TREZOR_MODEL == 'T' and UI2:
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/ui/components/tt/*.py'))
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/ui/constants/tt.py'))
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/ui/layouts/tt_v2/__init__.py'))
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/ui/layouts/tt/__init__.py'))
if EVERYTHING:
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/ui/layouts/tt/webauthn.py'))
elif TREZOR_MODEL == 'T':
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/ui/components/tt/*.py'))
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/ui/constants/tt.py'))
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/ui/layouts/tt/__init__.py'))
@ -672,11 +680,10 @@ def cargo_build():
features = ["model_tt"]
if BITCOIN_ONLY == "1":
features.append("bitcoin_only")
if PYOPT == "0":
features.append("ui")
features.append("ui_debug")
elif NEW_UI:
if UI2:
features.append("ui")
if PYOPT == "0":
features.append("ui_debug")
return f'cd embed/rust; cargo build --profile {RUST_PROFILE} --target-dir=../../build/unix/rust --no-default-features --features "{" ".join(features)}"'

@ -31,20 +31,28 @@
#if TREZOR_MODEL == T
// TT new rust UI
#if TREZOR_FONT_MEDIUM_ENABLE
#if TREZOR_UI2
#ifdef TREZOR_FONT_NORMAL_ENABLE
#include "font_tthoves_regular_18.h"
#define FONT_NORMAL_DATA Font_TTHoves_Regular_18
#define FONT_NORMAL_HEIGHT 18
#endif
#ifdef TREZOR_FONT_MEDIUM_ENABLE
#include "font_tthoves_medium_20.h"
#define FONT_MEDIUM_DATA Font_TTHoves_Medium_20
#define FONT_MEDIUM_HEIGHT 20
#endif
#ifdef TREZOR_FONT_BOLD_ENABLE
#include "font_tthoves_bold_16.h"
#define FONT_BOLD_DATA Font_TTHoves_Bold_16
#define FONT_BOLD_HEIGHT 16
#endif
#ifdef TREZOR_FONT_MONO_ENABLE
#include "font_robotomono_regular_20.h"
#define FONT_MONO_DATA Font_RobotoMono_Regular_20
#define FONT_MONO_HEIGHT 20
#endif
// TT old python UI
#else

@ -654,9 +654,11 @@ void dump_value_opt(FILE *out, mp_const_obj_t value, bool eval_short) {
dump_protodef(out, value);
}
#ifdef TREZOR_UI2
else if (mp_obj_is_type(value, ui_debug_layout_type())) {
dump_uilayout(out, value);
}
#endif
else {
print_type(out, "unknown", NULL, value, true);

@ -26,12 +26,12 @@
/// def layout_new_confirm_action(
/// *,
/// title: str,
/// action: str | None,
/// description: str | None,
/// verb: str | None,
/// verb_cancel: str | None,
/// hold: bool | None,
/// reverse: bool,
/// action: str | None = None,
/// description: str | None = None,
/// verb: str | None = None,
/// verb_cancel: str | None = None,
/// hold: bool | None = None,
/// reverse: bool = False,
/// ) -> object:
/// """Example layout."""
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(mod_trezorui2_layout_new_confirm_action_obj,

@ -2,21 +2,21 @@ from typing import *
# extmod/rustmods/modtrezorui2.c
def layout_new_example(text: str) -> None:
def layout_new_confirm_action(
*,
title: str,
action: str | None = None,
description: str | None = None,
verb: str | None = None,
verb_cancel: str | None = None,
hold: bool | None = None,
reverse: bool = False,
) -> object:
"""Example layout."""
# extmod/rustmods/modtrezorui2.c
def layout_new_confirm_action(
*,
title: str,
action: str | None,
description: str | None,
verb: str | None,
verb_cancel: str | None,
hold: bool | None,
reverse: bool,
) -> int:
def layout_new_example(text: str) -> object:
"""Example layout."""
@ -26,5 +26,5 @@ def layout_new_confirm_text(
title: str,
data: str,
description: str | None,
) -> int:
) -> object:
"""Example layout."""

@ -204,6 +204,8 @@ trezor.ui.layouts.tt.recovery
import trezor.ui.layouts.tt.recovery
trezor.ui.layouts.tt.reset
import trezor.ui.layouts.tt.reset
trezor.ui.layouts.tt_v2
import trezor.ui.layouts.tt_v2
trezor.ui.loader
import trezor.ui.loader
trezor.ui.popup

@ -444,60 +444,3 @@ class Layout(Component):
def wait_until_layout_is_running() -> Awaitable[None]: # type: ignore
while not layout_chan.takers:
yield
class RustLayout(Layout):
# pylint: disable=super-init-not-called
def __init__(self, layout: Any):
self.layout = layout
self.timer = loop.Timer()
self.layout.set_timer_fn(self.set_timer)
def set_timer(self, token: int, deadline: int) -> None:
self.timer.schedule(deadline, token)
def create_tasks(self) -> tuple[loop.Task, ...]:
return self.handle_input_and_rendering(), self.handle_timers()
if utils.MODEL == "T":
def handle_input_and_rendering(self) -> loop.Task: # type: ignore
touch = loop.wait(io.TOUCH)
display.clear()
self.layout.paint()
while True:
# Using `yield` instead of `await` to avoid allocations.
event, x, y = yield touch
workflow.idle_timer.touch()
msg = None
if event in (io.TOUCH_START, io.TOUCH_MOVE, io.TOUCH_END):
msg = self.layout.touch_event(event, x, y)
self.layout.paint()
if msg is not None:
raise Result(msg)
elif utils.MODEL == "1":
def handle_input_and_rendering(self) -> loop.Task: # type: ignore
button = loop.wait(io.BUTTON)
display.clear()
self.layout.paint()
while True:
# Using `yield` instead of `await` to avoid allocations.
event, button_num = yield button
workflow.idle_timer.touch()
msg = None
if event in (io.BUTTON_PRESSED, io.BUTTON_RELEASED):
msg = self.layout.button_event(event, button_num)
self.layout.paint()
if msg is not None:
raise Result(msg)
def handle_timers(self) -> loop.Task: # type: ignore
while True:
# Using `yield` instead of `await` to avoid allocations.
token = yield self.timer
msg = self.layout.timer(token)
self.layout.paint()
if msg is not None:
raise Result(msg)

@ -2,11 +2,20 @@ from trezor import utils
from .common import * # noqa: F401,F403
try:
ui2 = True
import trezorui2 # noqa: F401
except ImportError:
ui2 = False
# NOTE: using any import magic probably causes mypy not to check equivalence of
# layout type signatures across models
if utils.MODEL == "1":
from .t1 import * # noqa: F401,F403
elif utils.MODEL == "T":
from .tt import * # noqa: F401,F403
if not ui2:
from .tt import * # noqa: F401,F403
else:
from .tt_v2 import * # noqa: F401,F403
else:
raise ValueError("Unknown Trezor model")

@ -1,6 +1,6 @@
from typing import TYPE_CHECKING
from trezor import log, ui, wire
from trezor import io, log, loop, ui, wire, workflow
from trezor.enums import ButtonRequestType
from trezorui2 import layout_new_confirm_action, layout_new_confirm_text
@ -8,11 +8,49 @@ from trezorui2 import layout_new_confirm_action, layout_new_confirm_text
from .common import interact
if TYPE_CHECKING:
from typing import NoReturn, Type
from typing import Any, NoReturn, Type
ExceptionType = BaseException | Type[BaseException]
class _RustLayout(ui.Layout):
# pylint: disable=super-init-not-called
def __init__(self, layout: Any):
self.layout = layout
self.timer = loop.Timer()
self.layout.set_timer_fn(self.set_timer)
def set_timer(self, token: int, deadline: int) -> None:
self.timer.schedule(deadline, token)
def create_tasks(self) -> tuple[loop.Task, ...]:
return self.handle_input_and_rendering(), self.handle_timers()
def handle_input_and_rendering(self) -> loop.Task: # type: ignore
button = loop.wait(io.BUTTON)
ui.display.clear()
self.layout.paint()
while True:
# Using `yield` instead of `await` to avoid allocations.
event, button_num = yield button
workflow.idle_timer.touch()
msg = None
if event in (io.BUTTON_PRESSED, io.BUTTON_RELEASED):
msg = self.layout.button_event(event, button_num)
self.layout.paint()
if msg is not None:
raise ui.Result(msg)
def handle_timers(self) -> loop.Task: # type: ignore
while True:
# Using `yield` instead of `await` to avoid allocations.
token = yield self.timer
msg = self.layout.timer(token)
self.layout.paint()
if msg is not None:
raise ui.Result(msg)
async def confirm_action(
ctx: wire.GenericContext,
br_type: str,
@ -45,7 +83,7 @@ async def confirm_action(
result = await interact(
ctx,
ui.RustLayout(
_RustLayout(
layout_new_confirm_action(
title=title.upper(),
action=action,
@ -75,7 +113,7 @@ async def confirm_text(
) -> None:
result = await interact(
ctx,
ui.RustLayout(
_RustLayout(
layout_new_confirm_text(
title=title.upper(),
data=data,

@ -0,0 +1,452 @@
from typing import TYPE_CHECKING
from trezor import io, log, loop, ui, wire, workflow
from trezor.enums import ButtonRequestType
from trezorui2 import layout_new_confirm_action
from ...constants.tt import MONO_ADDR_PER_LINE
from ..common import interact
if TYPE_CHECKING:
from typing import Any, Awaitable, Iterable, NoReturn, Sequence
from ..common import PropertyType, ExceptionType
class _RustLayout(ui.Layout):
# pylint: disable=super-init-not-called
def __init__(self, layout: Any):
self.layout = layout
self.timer = loop.Timer()
self.layout.set_timer_fn(self.set_timer)
def set_timer(self, token: int, deadline: int) -> None:
self.timer.schedule(deadline, token)
def create_tasks(self) -> tuple[loop.Task, ...]:
return self.handle_input_and_rendering(), self.handle_timers()
def handle_input_and_rendering(self) -> loop.Task: # type: ignore
touch = loop.wait(io.TOUCH)
ui.display.clear()
self.layout.paint()
# self.layout.bounds()
while True:
# Using `yield` instead of `await` to avoid allocations.
event, x, y = yield touch
workflow.idle_timer.touch()
msg = None
if event in (io.TOUCH_START, io.TOUCH_MOVE, io.TOUCH_END):
msg = self.layout.touch_event(event, x, y)
self.layout.paint()
# self.layout.bounds()
if msg is not None:
raise ui.Result(msg)
def handle_timers(self) -> loop.Task: # type: ignore
while True:
# Using `yield` instead of `await` to avoid allocations.
token = yield self.timer
msg = self.layout.timer(token)
self.layout.paint()
if msg is not None:
raise ui.Result(msg)
async def confirm_action(
ctx: wire.GenericContext,
br_type: str,
title: str,
action: str | None = None,
description: str | None = None,
description_param: str | None = None,
description_param_font: int = ui.BOLD,
verb: str | bytes | None = "CONFIRM",
verb_cancel: str | bytes | None = None,
hold: bool = False,
hold_danger: bool = False,
icon: str | None = None,
icon_color: int | None = None,
reverse: bool = False,
larger_vspace: bool = False,
exc: ExceptionType = wire.ActionCancelled,
br_code: ButtonRequestType = ButtonRequestType.Other,
) -> None:
if isinstance(verb, bytes) or isinstance(verb_cancel, bytes):
raise NotImplementedError
elif isinstance(verb, str):
verb = verb.upper()
if description is not None and description_param is not None:
if description_param_font != ui.BOLD:
log.error(__name__, "confirm_action description_param_font not implemented")
description = description.format(description_param)
if hold:
log.error(__name__, "confirm_action hold not implemented")
if verb_cancel:
log.error(__name__, "confirm_action verb_cancel not implemented")
result = await interact(
ctx,
_RustLayout(
layout_new_confirm_action(
title=title.upper(),
action=action,
description=description,
verb=verb,
hold=hold,
reverse=reverse,
)
),
br_type,
br_code,
)
if result is not True:
raise exc
async def confirm_reset_device(
ctx: wire.GenericContext, prompt: str, recovery: bool = False
) -> None:
raise NotImplementedError
# TODO cleanup @ redesign
async def confirm_backup(ctx: wire.GenericContext) -> bool:
raise NotImplementedError
async def confirm_path_warning(
ctx: wire.GenericContext, path: str, path_type: str = "Path"
) -> None:
raise NotImplementedError
async def show_xpub(
ctx: wire.GenericContext, xpub: str, title: str, cancel: str
) -> None:
raise NotImplementedError
async def show_address(
ctx: wire.GenericContext,
address: str,
address_qr: str | None = None,
title: str = "Confirm address",
network: str | None = None,
multisig_index: int | None = None,
xpubs: Sequence[str] = (),
address_extra: str | None = None,
title_qr: str | None = None,
) -> None:
raise NotImplementedError
def show_pubkey(
ctx: wire.Context, pubkey: str, title: str = "Confirm public key"
) -> Awaitable[None]:
return confirm_blob(
ctx,
br_type="show_pubkey",
title="Confirm public key",
data=pubkey,
br_code=ButtonRequestType.PublicKey,
icon=ui.ICON_RECEIVE,
)
async def _show_modal(
ctx: wire.GenericContext,
br_type: str,
br_code: ButtonRequestType,
header: str,
subheader: str | None,
content: str,
button_confirm: str | None,
button_cancel: str | None,
icon: str,
icon_color: int,
exc: ExceptionType = wire.ActionCancelled,
) -> None:
raise NotImplementedError
async def show_error_and_raise(
ctx: wire.GenericContext,
br_type: str,
content: str,
header: str = "Error",
subheader: str | None = None,
button: str = "Close",
red: bool = False,
exc: ExceptionType = wire.ActionCancelled,
) -> NoReturn:
await _show_modal(
ctx,
br_type=br_type,
br_code=ButtonRequestType.Other,
header=header,
subheader=subheader,
content=content,
button_confirm=None,
button_cancel=button,
icon=ui.ICON_WRONG,
icon_color=ui.RED if red else ui.ORANGE_ICON,
exc=exc,
)
raise exc
def show_warning(
ctx: wire.GenericContext,
br_type: str,
content: str,
header: str = "Warning",
subheader: str | None = None,
button: str = "Try again",
br_code: ButtonRequestType = ButtonRequestType.Warning,
icon: str = ui.ICON_WRONG,
icon_color: int = ui.RED,
) -> Awaitable[None]:
return _show_modal(
ctx,
br_type=br_type,
br_code=br_code,
header=header,
subheader=subheader,
content=content,
button_confirm=button,
button_cancel=None,
icon=icon,
icon_color=icon_color,
)
def show_success(
ctx: wire.GenericContext,
br_type: str,
content: str,
subheader: str | None = None,
button: str = "Continue",
) -> Awaitable[None]:
return _show_modal(
ctx,
br_type=br_type,
br_code=ButtonRequestType.Success,
header="Success",
subheader=subheader,
content=content,
button_confirm=button,
button_cancel=None,
icon=ui.ICON_CONFIRM,
icon_color=ui.GREEN,
)
async def confirm_output(
ctx: wire.GenericContext,
address: str,
amount: str,
font_amount: int = ui.NORMAL, # TODO cleanup @ redesign
title: str = "Confirm sending",
subtitle: str | None = None, # TODO cleanup @ redesign
color_to: int = ui.FG, # TODO cleanup @ redesign
to_str: str = " to\n", # TODO cleanup @ redesign
to_paginated: bool = False, # TODO cleanup @ redesign
width: int = MONO_ADDR_PER_LINE,
width_paginated: int = MONO_ADDR_PER_LINE - 1,
br_code: ButtonRequestType = ButtonRequestType.ConfirmOutput,
icon: str = ui.ICON_SEND,
) -> None:
raise NotImplementedError
async def should_show_more(
ctx: wire.GenericContext,
title: str,
para: Iterable[tuple[int, str]],
button_text: str = "Show all",
br_type: str = "should_show_more",
br_code: ButtonRequestType = ButtonRequestType.Other,
icon: str = ui.ICON_DEFAULT,
icon_color: int = ui.ORANGE_ICON,
) -> bool:
raise NotImplementedError
async def confirm_blob(
ctx: wire.GenericContext,
br_type: str,
title: str,
data: bytes | str,
description: str | None = None,
hold: bool = False,
br_code: ButtonRequestType = ButtonRequestType.Other,
icon: str = ui.ICON_SEND, # TODO cleanup @ redesign
icon_color: int = ui.GREEN, # TODO cleanup @ redesign
ask_pagination: bool = False,
) -> None:
raise NotImplementedError
def confirm_address(
ctx: wire.GenericContext,
title: str,
address: str,
description: str | None = "Address:",
br_type: str = "confirm_address",
br_code: ButtonRequestType = ButtonRequestType.Other,
icon: str = ui.ICON_SEND, # TODO cleanup @ redesign
icon_color: int = ui.GREEN, # TODO cleanup @ redesign
) -> Awaitable[None]:
raise NotImplementedError
async def confirm_text(
ctx: wire.GenericContext,
br_type: str,
title: str,
data: str,
description: str | None = None,
br_code: ButtonRequestType = ButtonRequestType.Other,
icon: str = ui.ICON_SEND, # TODO cleanup @ redesign
icon_color: int = ui.GREEN, # TODO cleanup @ redesign
) -> None:
raise NotImplementedError
def confirm_amount(
ctx: wire.GenericContext,
title: str,
amount: str,
description: str = "Amount:",
br_type: str = "confirm_amount",
br_code: ButtonRequestType = ButtonRequestType.Other,
icon: str = ui.ICON_SEND, # TODO cleanup @ redesign
icon_color: int = ui.GREEN, # TODO cleanup @ redesign
) -> Awaitable[None]:
raise NotImplementedError
async def confirm_properties(
ctx: wire.GenericContext,
br_type: str,
title: str,
props: Iterable[PropertyType],
icon: str = ui.ICON_SEND, # TODO cleanup @ redesign
icon_color: int = ui.GREEN, # TODO cleanup @ redesign
hold: bool = False,
br_code: ButtonRequestType = ButtonRequestType.ConfirmOutput,
) -> None:
raise NotImplementedError
async def confirm_total(
ctx: wire.GenericContext,
total_amount: str,
fee_amount: str,
title: str = "Confirm transaction",
total_label: str = "Total amount:\n",
fee_label: str = "\nincluding fee:\n",
icon_color: int = ui.GREEN,
br_type: str = "confirm_total",
br_code: ButtonRequestType = ButtonRequestType.SignTx,
) -> None:
raise NotImplementedError
async def confirm_joint_total(
ctx: wire.GenericContext, spending_amount: str, total_amount: str
) -> None:
raise NotImplementedError
async def confirm_metadata(
ctx: wire.GenericContext,
br_type: str,
title: str,
content: str,
param: str | None = None,
br_code: ButtonRequestType = ButtonRequestType.SignTx,
hide_continue: bool = False,
hold: bool = False,
param_font: int = ui.BOLD,
icon: str = ui.ICON_SEND, # TODO cleanup @ redesign
icon_color: int = ui.GREEN, # TODO cleanup @ redesign
larger_vspace: bool = False, # TODO cleanup @ redesign
) -> None:
raise NotImplementedError
async def confirm_replacement(
ctx: wire.GenericContext, description: str, txid: str
) -> None:
raise NotImplementedError
async def confirm_modify_output(
ctx: wire.GenericContext,
address: str,
sign: int,
amount_change: str,
amount_new: str,
) -> None:
raise NotImplementedError
async def confirm_modify_fee(
ctx: wire.GenericContext,
sign: int,
user_fee_change: str,
total_fee_new: str,
) -> None:
raise NotImplementedError
async def confirm_coinjoin(
ctx: wire.GenericContext, fee_per_anonymity: str | None, total_fee: str
) -> None:
raise NotImplementedError
# TODO cleanup @ redesign
async def confirm_sign_identity(
ctx: wire.GenericContext, proto: str, identity: str, challenge_visual: str | None
) -> None:
raise NotImplementedError
async def confirm_signverify(
ctx: wire.GenericContext, coin: str, message: str, address: str, verify: bool
) -> None:
raise NotImplementedError
async def show_popup(
title: str,
description: str,
subtitle: str | None = None,
description_param: str = "",
timeout_ms: int = 3000,
) -> None:
raise NotImplementedError
def draw_simple_text(title: str, description: str = "") -> None:
raise NotImplementedError
async def request_passphrase_on_device(ctx: wire.GenericContext, max_len: int) -> str:
raise NotImplementedError
async def request_pin_on_device(
ctx: wire.GenericContext,
prompt: str,
attempts_remaining: int | None,
allow_cancel: bool,
) -> str:
raise NotImplementedError
Loading…
Cancel
Save