diff --git a/core/src/apps/ethereum/layout.py b/core/src/apps/ethereum/layout.py index aeea41ff3..e2effe0c5 100644 --- a/core/src/apps/ethereum/layout.py +++ b/core/src/apps/ethereum/layout.py @@ -3,11 +3,7 @@ from ubinascii import hexlify from trezor import ui from trezor.enums import ButtonRequestType from trezor.strings import format_amount -from trezor.ui.components.tt.text import Text -from trezor.utils import chunks - -from apps.common.confirm import require_confirm, require_hold_to_confirm -from apps.common.layout import split_address +from trezor.ui.layouts import confirm_hex, confirm_output, confirm_total_ethereum from . import networks, tokens from .address import address_from_bytes @@ -18,49 +14,55 @@ async def require_confirm_tx(ctx, to_bytes, value, chain_id, token=None, tx_type to_str = address_from_bytes(to_bytes, networks.by_chain_id(chain_id)) else: to_str = "new contract?" - text = Text("Confirm sending", ui.ICON_SEND, ui.GREEN, new_lines=False) - text.bold(format_ethereum_amount(value, token, chain_id, tx_type)) - text.normal(ui.GREY, " to ", ui.FG) - for to_line in split_address(to_str): - text.br() - text.mono(to_line) - # we use SignTx, not ConfirmOutput, for compatibility with T1 - await require_confirm(ctx, text, ButtonRequestType.SignTx) + await confirm_output( + ctx, + address=to_str, + amount=format_ethereum_amount(value, token, chain_id, tx_type), + font_amount=ui.BOLD, + color_to=ui.GREY, + br_code=ButtonRequestType.SignTx, + ) async def require_confirm_fee( ctx, spending, gas_price, gas_limit, chain_id, token=None, tx_type=None ): - text = Text("Confirm transaction", ui.ICON_SEND, ui.GREEN, new_lines=False) - text.bold(format_ethereum_amount(spending, token, chain_id, tx_type)) - text.normal(" ", ui.GREY, "Gas price:", ui.FG) - text.bold(format_ethereum_amount(gas_price, None, chain_id, tx_type)) - text.normal(" ", ui.GREY, "Maximum fee:", ui.FG) - text.bold(format_ethereum_amount(gas_price * gas_limit, None, chain_id, tx_type)) - await require_hold_to_confirm(ctx, text, ButtonRequestType.SignTx) + await confirm_total_ethereum( + ctx, + format_ethereum_amount(spending, token, chain_id, tx_type), + format_ethereum_amount(gas_price, None, chain_id, tx_type), + format_ethereum_amount(gas_price * gas_limit, None, chain_id, tx_type), + ) async def require_confirm_unknown_token(ctx, address_bytes): - text = Text("Unknown token", ui.ICON_SEND, ui.ORANGE, new_lines=False) - text.normal(ui.GREY, "Contract:", ui.FG) contract_address_hex = "0x" + hexlify(address_bytes).decode() - text.mono(*split_data(contract_address_hex)) - await require_confirm(ctx, text, ButtonRequestType.SignTx) - - -def split_data(data): - return chunks(data, 18) + await confirm_hex( + ctx, + "confirm_unknown", + title="Unknown token", + data=contract_address_hex, + truncate=True, + description="Contract:", + color_description=ui.GREY, + icon_color=ui.ORANGE, + br_code=ButtonRequestType.SignTx, + ) async def require_confirm_data(ctx, data, data_total): data_str = hexlify(data[:36]).decode() if data_total > 36: data_str = data_str[:-2] + ".." - text = Text("Confirm data", ui.ICON_SEND, ui.GREEN) - text.bold("Size: %d bytes" % data_total) - text.mono(*split_data(data_str)) - # we use SignTx, not ConfirmOutput, for compatibility with T1 - await require_confirm(ctx, text, ButtonRequestType.SignTx) + await confirm_hex( + ctx, + "confirm_data", + title="Confirm data", + data=data_str, + truncate=True, + subtitle="Size: %d bytes" % data_total, + br_code=ButtonRequestType.SignTx, + ) def format_ethereum_amount(value: int, token, chain_id: int, tx_type=None): diff --git a/core/src/trezor/ui/layouts/tt.py b/core/src/trezor/ui/layouts/tt.py index 8c3299b27..f41d84909 100644 --- a/core/src/trezor/ui/layouts/tt.py +++ b/core/src/trezor/ui/layouts/tt.py @@ -53,6 +53,7 @@ __all__ = ( "confirm_decred_sstx_submission", "confirm_hex", "confirm_total", + "confirm_total_ethereum", "confirm_joint_total", "confirm_metadata", "confirm_replacement", @@ -215,7 +216,7 @@ def _truncate_hex( width: int = MONO_HEX_PER_LINE, middle: bool = False, ) -> Iterator[str]: - if len(hex_data) >= width * lines: + if len(hex_data) > width * lines: if middle: hex_data = ( hex_data[: lines * width // 2 - 1] @@ -438,12 +439,15 @@ async def confirm_output( ctx: wire.GenericContext, address: str, amount: str, + font_amount: int = ui.NORMAL, # TODO cleanup @ redesign + color_to: int = ui.FG, # TODO cleanup @ redesign + br_code: ButtonRequestType = ButtonRequestType.ConfirmOutput, ) -> None: text = Text("Confirm sending", ui.ICON_SEND, ui.GREEN, new_lines=False) - text.normal(amount + " to\n") + text.content = [font_amount, amount, ui.NORMAL, color_to, " to\n", ui.FG] text.mono(*_split_address(address)) await raise_if_cancelled( - interact(ctx, Confirm(text), "confirm_output", ButtonRequestType.ConfirmOutput) + interact(ctx, Confirm(text), "confirm_output", br_code) ) @@ -475,14 +479,18 @@ async def confirm_hex( br_code: ButtonRequestType = ButtonRequestType.Other, icon: str = ui.ICON_SEND, # TODO cleanup @ redesign icon_color: int = ui.GREEN, # TODO cleanup @ redesign + font_description: int = ui.NORMAL, # TODO cleanup @ redesign + color_description: int = ui.FG, # TODO cleanup @ redesign width: int = MONO_HEX_PER_LINE, truncate_middle: bool = False, ) -> None: text = Text(title, icon, icon_color, new_lines=False) description_lines = 0 if description is not None: - description_lines = Span(description, 0, ui.NORMAL).count_lines() - text.normal(description) + description_lines = Span(description, 0, font_description).count_lines() + text.content.extend( + (font_description, color_description, description, ui.FG) + ) text.br() text.mono( *_truncate_hex( @@ -509,6 +517,21 @@ async def confirm_total( ) +# TODO cleanup @ redesign +async def confirm_total_ethereum( + ctx: wire.GenericContext, total_amount: str, gas_price: str, fee_max: str +) -> None: + text = Text("Confirm transaction", ui.ICON_SEND, ui.GREEN, new_lines=False) + text.bold(total_amount) + text.normal(" ", ui.GREY, "Gas price:", ui.FG) + text.bold(gas_price) + text.normal(" ", ui.GREY, "Maximum fee:", ui.FG) + text.bold(fee_max) + await raise_if_cancelled( + interact(ctx, HoldToConfirm(text), "confirm_total", ButtonRequestType.SignTx) + ) + + async def confirm_joint_total( ctx: wire.GenericContext, spending_amount: str, total_amount: str ) -> None: