mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-01-02 03:20:59 +00:00
feat(core): add progress to Ethereum transaction signing
This commit is contained in:
parent
09d3301785
commit
692eee3e07
@ -151,7 +151,7 @@ fn new_confirm_output_obj(_args: &[Obj], kwargs: &Map) -> Result<Obj, error::Err
|
|||||||
theme::ICON_CHEVRON_RIGHT,
|
theme::ICON_CHEVRON_RIGHT,
|
||||||
TR::address_details__account_info.into(),
|
TR::address_details__account_info.into(),
|
||||||
);
|
);
|
||||||
menu_items.push(MENU_ITEM_ACCOUNT_INFO);
|
unwrap!(menu_items.push(MENU_ITEM_ACCOUNT_INFO));
|
||||||
}
|
}
|
||||||
menu = menu.danger(
|
menu = menu.danger(
|
||||||
theme::ICON_CANCEL,
|
theme::ICON_CANCEL,
|
||||||
|
@ -150,14 +150,14 @@ impl ConfirmSummary {
|
|||||||
theme::ICON_CHEVRON_RIGHT,
|
theme::ICON_CHEVRON_RIGHT,
|
||||||
TR::confirm_total__title_fee.into(),
|
TR::confirm_total__title_fee.into(),
|
||||||
);
|
);
|
||||||
menu_items.push(MENU_ITEM_FEE_INFO);
|
unwrap!(menu_items.push(MENU_ITEM_FEE_INFO));
|
||||||
}
|
}
|
||||||
if has_account_info {
|
if has_account_info {
|
||||||
menu = menu.item(
|
menu = menu.item(
|
||||||
theme::ICON_CHEVRON_RIGHT,
|
theme::ICON_CHEVRON_RIGHT,
|
||||||
TR::address_details__account_info.into(),
|
TR::address_details__account_info.into(),
|
||||||
);
|
);
|
||||||
menu_items.push(MENU_ITEM_ACCOUNT_INFO);
|
unwrap!(menu_items.push(MENU_ITEM_ACCOUNT_INFO));
|
||||||
}
|
}
|
||||||
menu = menu.danger(
|
menu = menu.danger(
|
||||||
theme::ICON_CANCEL,
|
theme::ICON_CANCEL,
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
|
from trezor import utils
|
||||||
from trezor.crypto import rlp
|
from trezor.crypto import rlp
|
||||||
from trezor.messages import EthereumTxRequest
|
from trezor.messages import EthereumTxRequest
|
||||||
from trezor.utils import BufferReader
|
from trezor.utils import BufferReader
|
||||||
@ -19,6 +20,7 @@ if TYPE_CHECKING:
|
|||||||
EthereumTokenInfo,
|
EthereumTokenInfo,
|
||||||
EthereumTxAck,
|
EthereumTxAck,
|
||||||
)
|
)
|
||||||
|
from trezor.ui.layouts.common import ProgressLayout
|
||||||
|
|
||||||
from apps.common.keychain import Keychain
|
from apps.common.keychain import Keychain
|
||||||
|
|
||||||
@ -67,6 +69,10 @@ async def sign_tx(
|
|||||||
)
|
)
|
||||||
await confirm_tx_data(msg, defs, address_bytes, maximum_fee, fee_items, data_total)
|
await confirm_tx_data(msg, defs, address_bytes, maximum_fee, fee_items, data_total)
|
||||||
|
|
||||||
|
_start_progress()
|
||||||
|
|
||||||
|
_render_progress(30)
|
||||||
|
|
||||||
# sign
|
# sign
|
||||||
data = bytearray()
|
data = bytearray()
|
||||||
data += msg.data_initial_chunk
|
data += msg.data_initial_chunk
|
||||||
@ -89,6 +95,8 @@ async def sign_tx(
|
|||||||
rlp.write_header(sha, data_total, rlp.STRING_HEADER_BYTE, data)
|
rlp.write_header(sha, data_total, rlp.STRING_HEADER_BYTE, data)
|
||||||
sha.extend(data)
|
sha.extend(data)
|
||||||
|
|
||||||
|
_render_progress(60)
|
||||||
|
|
||||||
while data_left > 0:
|
while data_left > 0:
|
||||||
resp = await send_request_chunk(data_left)
|
resp = await send_request_chunk(data_left)
|
||||||
data_left -= len(resp.data_chunk)
|
data_left -= len(resp.data_chunk)
|
||||||
@ -102,6 +110,8 @@ async def sign_tx(
|
|||||||
digest = sha.get_digest()
|
digest = sha.get_digest()
|
||||||
result = _sign_digest(msg, keychain, digest)
|
result = _sign_digest(msg, keychain, digest)
|
||||||
|
|
||||||
|
_finish_progress()
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
@ -376,3 +386,30 @@ async def _handle_staking_tx_claim(
|
|||||||
raise DataError("Invalid staking transaction call")
|
raise DataError("Invalid staking transaction call")
|
||||||
|
|
||||||
await require_confirm_claim(staking_addr, maximum_fee, fee_items, network, chunkify)
|
await require_confirm_claim(staking_addr, maximum_fee, fee_items, network, chunkify)
|
||||||
|
|
||||||
|
|
||||||
|
_progress_obj: ProgressLayout | None = None
|
||||||
|
|
||||||
|
|
||||||
|
def _start_progress() -> None:
|
||||||
|
from trezor import TR, workflow
|
||||||
|
from trezor.ui.layouts.progress import progress
|
||||||
|
|
||||||
|
global _progress_obj
|
||||||
|
|
||||||
|
if not utils.DISABLE_ANIMATION:
|
||||||
|
# Because we are drawing to the screen manually, without a layout, we
|
||||||
|
# should make sure that no other layout is running.
|
||||||
|
workflow.close_others()
|
||||||
|
_progress_obj = progress(title=TR.progress__signing_transaction)
|
||||||
|
|
||||||
|
|
||||||
|
def _render_progress(progress: int) -> None:
|
||||||
|
global _progress_obj
|
||||||
|
if _progress_obj is not None:
|
||||||
|
_progress_obj.report(progress)
|
||||||
|
|
||||||
|
|
||||||
|
def _finish_progress() -> None:
|
||||||
|
global _progress_obj
|
||||||
|
_progress_obj = None
|
||||||
|
@ -1028,6 +1028,7 @@ if not utils.BITCOIN_ONLY:
|
|||||||
title=TR.words__recipient,
|
title=TR.words__recipient,
|
||||||
chunkify=chunkify,
|
chunkify=chunkify,
|
||||||
cancel_text=TR.buttons__cancel,
|
cancel_text=TR.buttons__cancel,
|
||||||
|
br_code=ButtonRequestType.Other,
|
||||||
)
|
)
|
||||||
|
|
||||||
await _confirm_summary(
|
await _confirm_summary(
|
||||||
|
@ -125,6 +125,7 @@ def test_signtx_fee_info(client: Client):
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.skip_t1b1("T1 does not support input flows")
|
@pytest.mark.skip_t1b1("T1 does not support input flows")
|
||||||
|
@pytest.mark.skip_t3t1("Cancel on Summary means Cancel Sign. No going back here!")
|
||||||
def test_signtx_go_back_from_summary(client: Client):
|
def test_signtx_go_back_from_summary(client: Client):
|
||||||
input_flow = InputFlowEthereumSignTxGoBackFromSummary(client).get()
|
input_flow = InputFlowEthereumSignTxGoBackFromSummary(client).get()
|
||||||
_do_test_signtx(
|
_do_test_signtx(
|
||||||
|
@ -379,10 +379,11 @@ class EthereumFlow:
|
|||||||
info: bool = False,
|
info: bool = False,
|
||||||
go_back_from_summary: bool = False,
|
go_back_from_summary: bool = False,
|
||||||
) -> BRGeneratorType:
|
) -> BRGeneratorType:
|
||||||
yield
|
|
||||||
TR.assert_equals(self.debug.wait_layout().title(), "words__recipient")
|
|
||||||
|
|
||||||
if self.client.model in (models.T2T1, models.T3T1):
|
yield
|
||||||
|
|
||||||
|
if self.client.model in (models.T2T1,):
|
||||||
|
TR.assert_equals(self.debug.wait_layout().title(), "words__recipient")
|
||||||
if cancel:
|
if cancel:
|
||||||
self.debug.press_no()
|
self.debug.press_no()
|
||||||
else:
|
else:
|
||||||
@ -409,7 +410,13 @@ class EthereumFlow:
|
|||||||
)
|
)
|
||||||
self.debug.press_no(wait=True)
|
self.debug.press_no(wait=True)
|
||||||
self.debug.press_yes()
|
self.debug.press_yes()
|
||||||
else:
|
|
||||||
|
yield
|
||||||
|
elif self.client.model in (
|
||||||
|
models.T2B1,
|
||||||
|
models.T3B1,
|
||||||
|
):
|
||||||
|
TR.assert_equals(self.debug.wait_layout().title(), "words__recipient")
|
||||||
if cancel:
|
if cancel:
|
||||||
self.debug.press_left()
|
self.debug.press_left()
|
||||||
else:
|
else:
|
||||||
@ -436,6 +443,49 @@ class EthereumFlow:
|
|||||||
self.debug.press_left(wait=True)
|
self.debug.press_left(wait=True)
|
||||||
self.debug.press_middle()
|
self.debug.press_middle()
|
||||||
|
|
||||||
|
yield
|
||||||
|
elif self.client.model in (models.T3T1,):
|
||||||
|
TR.assert_equals(
|
||||||
|
self.debug.wait_layout().title().split("\n")[0], "words__address"
|
||||||
|
)
|
||||||
|
TR.assert_equals(
|
||||||
|
self.debug.wait_layout().title().split("\n")[1], "words__recipient"
|
||||||
|
)
|
||||||
|
if cancel:
|
||||||
|
self.debug.press_no()
|
||||||
|
else:
|
||||||
|
self.debug.press_yes()
|
||||||
|
yield
|
||||||
|
TR.assert_equals(
|
||||||
|
self.debug.wait_layout().title(), "words__title_summary"
|
||||||
|
)
|
||||||
|
TR.assert_in(
|
||||||
|
self.debug.wait_layout().text_content(), "send__maximum_fee"
|
||||||
|
)
|
||||||
|
if go_back_from_summary:
|
||||||
|
self.debug.press_no()
|
||||||
|
yield
|
||||||
|
self.debug.press_yes()
|
||||||
|
yield
|
||||||
|
if info:
|
||||||
|
self.debug.click(buttons.CORNER_BUTTON, wait=True)
|
||||||
|
self.debug.synchronize_at("VerticalMenu")
|
||||||
|
self.debug.click(buttons.VERTICAL_MENU[0], wait=True)
|
||||||
|
TR.assert_in(
|
||||||
|
self.debug.wait_layout().text_content(), "ethereum__gas_limit"
|
||||||
|
)
|
||||||
|
TR.assert_in(
|
||||||
|
self.debug.wait_layout().text_content(), "ethereum__gas_price"
|
||||||
|
)
|
||||||
|
self.debug.click(buttons.CORNER_BUTTON, wait=True)
|
||||||
|
self.debug.click(buttons.CORNER_BUTTON, wait=True)
|
||||||
|
self.debug.swipe_up()
|
||||||
|
self.debug.wait_layout()
|
||||||
|
self.debug.click(buttons.TAP_TO_CONFIRM)
|
||||||
|
yield
|
||||||
|
else:
|
||||||
|
raise ValueError("Unknown model!")
|
||||||
|
|
||||||
def confirm_tx_staking(
|
def confirm_tx_staking(
|
||||||
self,
|
self,
|
||||||
info: bool = False,
|
info: bool = False,
|
||||||
@ -484,6 +534,8 @@ class EthereumFlow:
|
|||||||
self.debug.press_no(wait=True)
|
self.debug.press_no(wait=True)
|
||||||
self.debug.press_yes()
|
self.debug.press_yes()
|
||||||
yield
|
yield
|
||||||
|
|
||||||
|
self.debug.press_yes()
|
||||||
else:
|
else:
|
||||||
# confirm intro
|
# confirm intro
|
||||||
if info:
|
if info:
|
||||||
@ -513,3 +565,5 @@ class EthereumFlow:
|
|||||||
self.debug.press_left(wait=True)
|
self.debug.press_left(wait=True)
|
||||||
self.debug.press_middle()
|
self.debug.press_middle()
|
||||||
yield
|
yield
|
||||||
|
|
||||||
|
self.debug.press_yes()
|
||||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user