From 19bae93d929424e28f8e5f2f914d7e3903036560 Mon Sep 17 00:00:00 2001 From: Pavol Rusnak Date: Wed, 28 Feb 2018 02:09:10 +0100 Subject: [PATCH] src/apps/ethereum: fix ethereum ui --- src/apps/ethereum/layout.py | 52 +++++++++++++++++++++++------------- src/apps/ethereum/sign_tx.py | 17 +++++++++--- 2 files changed, 47 insertions(+), 22 deletions(-) diff --git a/src/apps/ethereum/layout.py b/src/apps/ethereum/layout.py index 8f89da1c..4dae5cbc 100644 --- a/src/apps/ethereum/layout.py +++ b/src/apps/ethereum/layout.py @@ -5,30 +5,45 @@ from trezor.messages import ButtonRequestType from trezor.ui.text import Text from ubinascii import hexlify from . import networks +from .get_address import _ethereum_address_hex -async def confirm_tx(ctx, to, value, chain_id, token=None): # TODO: wording - str_to = '0x' + hexlify(to).decode() # TODO: use ethereum address format - content = Text('Confirm transaction', ui.ICON_DEFAULT, +async def confirm_tx(ctx, to, value, chain_id, token=None): + if to: + str_to = _ethereum_address_hex(to) + else: + str_to = 'new contract?' + content = Text('Confirm sending', ui.ICON_SEND, ui.BOLD, format_ethereum_amount(value, token, chain_id), ui.NORMAL, 'to', - ui.MONO, *split_address(str_to)) + ui.MONO, *split_address(str_to), + icon_color=ui.GREEN) return await confirm(ctx, content, ButtonRequestType.SignTx) # we use SignTx, not ConfirmOutput, for compatibility with T1 -async def confirm_fee(ctx, spending, gas_price, gas_limit, chain_id, token=None): # TODO: wording - content = Text('Confirm fee', ui.ICON_DEFAULT, - 'Sending: %s' % format_ethereum_amount(spending, token, chain_id), - 'Gas: %s' % format_ethereum_amount(gas_price, token, chain_id), - 'Limit: %s' % format_ethereum_amount(gas_limit, token, chain_id)) +async def confirm_fee(ctx, spending, gas_price, gas_limit, chain_id, token=None): + content = Text('Confirm transaction', ui.ICON_SEND, + ui.BOLD, format_ethereum_amount(spending, token, chain_id), + ui.NORMAL, 'Gas:', + ui.BOLD, format_ethereum_amount(gas_price, token, chain_id), + ui.NORMAL, 'Limit:', + ui.BOLD, format_ethereum_amount(gas_limit, token, chain_id), + icon_color=ui.GREEN) return await hold_to_confirm(ctx, content, ButtonRequestType.SignTx) -async def confirm_data(ctx, data, data_total): # TODO: wording - str_data = hexlify(data[:8]).decode() + '..' - content = Text('Confirm data:', ui.ICON_DEFAULT, - ui.MONO, str_data, - 'Total: ', str(data_total) + 'B') +def split_data(data): + return chunks(data, 18) + + +async def confirm_data(ctx, data, data_total): + str_data = hexlify(data[:36]).decode() + if data_total > 36: + str_data = str_data[:-2] + '..' + content = Text('Confirm data', ui.ICON_SEND, + ui.BOLD, 'Size: %d bytes' % data_total, + ui.MONO, *split_data(str_data), + icon_color=ui.GREEN) return await confirm(ctx, content, ButtonRequestType.SignTx) # we use SignTx, not ConfirmOutput, for compatibility with T1 @@ -41,11 +56,12 @@ def format_ethereum_amount(value, token, chain_id): if token: suffix = token['symbol'] decimals = token['decimal'] - elif value < 1e18: - suffix = 'Wei' - decimals = 0 else: - decimals = 18 suffix = networks.suffix_by_chain_id(chain_id) + decimals = 18 + + if value < 1e18: + suffix = 'Wei ' + suffix + decimals = 0 return '%s %s' % (format_amount(value, decimals), suffix) diff --git a/src/apps/ethereum/sign_tx.py b/src/apps/ethereum/sign_tx.py index 8706f189..9d2a2970 100644 --- a/src/apps/ethereum/sign_tx.py +++ b/src/apps/ethereum/sign_tx.py @@ -3,6 +3,7 @@ from trezor.messages.EthereumTxRequest import EthereumTxRequest from trezor.messages import FailureType from trezor.utils import HashWriter from trezor.crypto import rlp +from trezor import wire from apps.ethereum import tokens, layout # maximum supported chain id @@ -27,14 +28,22 @@ async def ethereum_sign_tx(ctx, msg): token = tokens.token_by_chain_address(msg.chain_id, msg.to) if token is None: - await layout.confirm_tx(ctx, msg.to, msg.value, msg.chain_id) + confirmed = await layout.confirm_tx(ctx, msg.to, msg.value, msg.chain_id) + if not confirmed: + raise wire.FailureError(FailureType.ActionCancelled, 'Cancelled') else: - await layout.confirm_tx(ctx, msg.data_initial_chunk[16:36], msg.data_initial_chunk[36:68], msg.chain_id, token) + confirmed = await layout.confirm_tx(ctx, msg.data_initial_chunk[16:36], msg.data_initial_chunk[36:68], msg.chain_id, token) + if not confirmed: + raise wire.FailureError(FailureType.ActionCancelled, 'Cancelled') if token is None and msg.data_length > 0: - await layout.confirm_data(ctx, msg.data_initial_chunk, data_total) + confirmed = await layout.confirm_data(ctx, msg.data_initial_chunk, data_total) + if not confirmed: + raise wire.FailureError(FailureType.ActionCancelled, 'Cancelled') - await layout.confirm_fee(ctx, msg.value, msg.gas_price, msg.gas_limit, msg.chain_id, token) + confirmed = await layout.confirm_fee(ctx, msg.value, msg.gas_price, msg.gas_limit, msg.chain_id, token) + if not confirmed: + raise wire.FailureError(FailureType.ActionCancelled, 'Cancelled') data = bytearray() data += msg.data_initial_chunk