1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-11-18 05:28:40 +00:00

docs(core): add method signatures for LayoutObj to mocks (fixes #2672)

feat(core): annotate CONFIRMED/CANCELLED/INFO as fake class UiResult
This commit is contained in:
matejcik 2023-06-27 16:01:21 +02:00 committed by matejcik
parent 99457bbcb0
commit 0304484ca6
5 changed files with 302 additions and 173 deletions

View File

@ -9,7 +9,7 @@ static void _librust_qstrs(void) {
MP_QSTR_CANCELLED; MP_QSTR_CANCELLED;
MP_QSTR_CONFIRMED; MP_QSTR_CONFIRMED;
MP_QSTR_INFO; MP_QSTR_INFO;
MP_QSTR_Layout; MP_QSTR_LayoutObj;
MP_QSTR_MESSAGE_NAME; MP_QSTR_MESSAGE_NAME;
MP_QSTR_MESSAGE_WIRE_TYPE; MP_QSTR_MESSAGE_WIRE_TYPE;
MP_QSTR_Msg; MP_QSTR_Msg;

View File

@ -249,7 +249,7 @@ impl LayoutObj {
fn obj_type() -> &'static Type { fn obj_type() -> &'static Type {
static TYPE: Type = obj_type! { static TYPE: Type = obj_type! {
name: Qstr::MP_QSTR_Layout, name: Qstr::MP_QSTR_LayoutObj,
locals: &obj_dict!(obj_map! { locals: &obj_dict!(obj_map! {
Qstr::MP_QSTR_attach_timer_fn => obj_fn_2!(ui_layout_attach_timer_fn).as_obj(), Qstr::MP_QSTR_attach_timer_fn => obj_fn_2!(ui_layout_attach_timer_fn).as_obj(),
Qstr::MP_QSTR_touch_event => obj_fn_var!(4, 4, ui_layout_touch_event).as_obj(), Qstr::MP_QSTR_touch_event => obj_fn_var!(4, 4, ui_layout_touch_event).as_obj(),

View File

@ -1708,13 +1708,13 @@ extern "C" fn new_show_wait_text(message: Obj) -> Obj {
pub static mp_module_trezorui2: Module = obj_module! { pub static mp_module_trezorui2: Module = obj_module! {
Qstr::MP_QSTR___name__ => Qstr::MP_QSTR_trezorui2.to_obj(), Qstr::MP_QSTR___name__ => Qstr::MP_QSTR_trezorui2.to_obj(),
/// CONFIRMED: object /// CONFIRMED: UiResult
Qstr::MP_QSTR_CONFIRMED => CONFIRMED.as_obj(), Qstr::MP_QSTR_CONFIRMED => CONFIRMED.as_obj(),
/// CANCELLED: object /// CANCELLED: UiResult
Qstr::MP_QSTR_CANCELLED => CANCELLED.as_obj(), Qstr::MP_QSTR_CANCELLED => CANCELLED.as_obj(),
/// INFO: object /// INFO: UiResult
Qstr::MP_QSTR_INFO => INFO.as_obj(), Qstr::MP_QSTR_INFO => INFO.as_obj(),
/// def disable_animation(disable: bool) -> None: /// def disable_animation(disable: bool) -> None:
@ -1735,7 +1735,7 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// hold: bool = False, /// hold: bool = False,
/// hold_danger: bool = False, # unused on TR /// hold_danger: bool = False, # unused on TR
/// reverse: bool = False, /// reverse: bool = False,
/// ) -> object: /// ) -> LayoutObj[UiResult]:
/// """Confirm action.""" /// """Confirm action."""
Qstr::MP_QSTR_confirm_action => obj_fn_kw!(0, new_confirm_action).as_obj(), Qstr::MP_QSTR_confirm_action => obj_fn_kw!(0, new_confirm_action).as_obj(),
@ -1757,7 +1757,7 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// verb_cancel: str | None = None, /// verb_cancel: str | None = None,
/// hold: bool = False, /// hold: bool = False,
/// chunkify: bool = False, /// chunkify: bool = False,
/// ) -> object: /// ) -> LayoutObj[UiResult]:
/// """Confirm byte sequence data.""" /// """Confirm byte sequence data."""
Qstr::MP_QSTR_confirm_blob => obj_fn_kw!(0, new_confirm_blob).as_obj(), Qstr::MP_QSTR_confirm_blob => obj_fn_kw!(0, new_confirm_blob).as_obj(),
@ -1769,7 +1769,7 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// extra: str | None, # unused on TR /// extra: str | None, # unused on TR
/// verb: str = "CONFIRM", /// verb: str = "CONFIRM",
/// chunkify: bool = False, /// chunkify: bool = False,
/// ) -> object: /// ) -> LayoutObj[UiResult]:
/// """Confirm address.""" /// """Confirm address."""
Qstr::MP_QSTR_confirm_address => obj_fn_kw!(0, new_confirm_address).as_obj(), Qstr::MP_QSTR_confirm_address => obj_fn_kw!(0, new_confirm_address).as_obj(),
@ -1779,7 +1779,7 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// title: str, /// title: str,
/// items: list[tuple[str | None, str | bytes | None, bool]], /// items: list[tuple[str | None, str | bytes | None, bool]],
/// hold: bool = False, /// hold: bool = False,
/// ) -> object: /// ) -> LayoutObj[UiResult]:
/// """Confirm list of key-value pairs. The third component in the tuple should be True if /// """Confirm list of key-value pairs. The third component in the tuple should be True if
/// the value is to be rendered as binary with monospace font, False otherwise. /// the value is to be rendered as binary with monospace font, False otherwise.
/// This only concerns the text style, you need to decode the value to UTF-8 in python.""" /// This only concerns the text style, you need to decode the value to UTF-8 in python."""
@ -1789,11 +1789,11 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// *, /// *,
/// title: str, /// title: str,
/// button: str, /// button: str,
/// ) -> object: /// ) -> LayoutObj[UiResult]:
/// """Confirm TOS before device setup.""" /// """Confirm TOS before device setup."""
Qstr::MP_QSTR_confirm_reset_device => obj_fn_kw!(0, new_confirm_reset_device).as_obj(), Qstr::MP_QSTR_confirm_reset_device => obj_fn_kw!(0, new_confirm_reset_device).as_obj(),
/// def confirm_backup() -> object: /// def confirm_backup() -> LayoutObj[UiResult]:
/// """Strongly recommend user to do backup.""" /// """Strongly recommend user to do backup."""
Qstr::MP_QSTR_confirm_backup => obj_fn_kw!(0, new_confirm_backup).as_obj(), Qstr::MP_QSTR_confirm_backup => obj_fn_kw!(0, new_confirm_backup).as_obj(),
@ -1804,7 +1804,7 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// account: str | None, /// account: str | None,
/// path: str | None, /// path: str | None,
/// xpubs: list[tuple[str, str]], /// xpubs: list[tuple[str, str]],
/// ) -> object: /// ) -> LayoutObj[UiResult]:
/// """Show address details - QR code, account, path, cosigner xpubs.""" /// """Show address details - QR code, account, path, cosigner xpubs."""
Qstr::MP_QSTR_show_address_details => obj_fn_kw!(0, new_show_address_details).as_obj(), Qstr::MP_QSTR_show_address_details => obj_fn_kw!(0, new_show_address_details).as_obj(),
@ -1815,7 +1815,7 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// value: str, /// value: str,
/// verb: str | None = None, /// verb: str | None = None,
/// hold: bool = False, /// hold: bool = False,
/// ) -> object: /// ) -> LayoutObj[UiResult]:
/// """Confirm value.""" /// """Confirm value."""
Qstr::MP_QSTR_confirm_value => obj_fn_kw!(0, new_confirm_value).as_obj(), Qstr::MP_QSTR_confirm_value => obj_fn_kw!(0, new_confirm_value).as_obj(),
@ -1823,7 +1823,7 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// *, /// *,
/// spending_amount: str, /// spending_amount: str,
/// total_amount: str, /// total_amount: str,
/// ) -> object: /// ) -> LayoutObj[UiResult]:
/// """Confirm total if there are external inputs.""" /// """Confirm total if there are external inputs."""
Qstr::MP_QSTR_confirm_joint_total => obj_fn_kw!(0, new_confirm_joint_total).as_obj(), Qstr::MP_QSTR_confirm_joint_total => obj_fn_kw!(0, new_confirm_joint_total).as_obj(),
@ -1832,7 +1832,7 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// sign: int, /// sign: int,
/// amount_change: str, /// amount_change: str,
/// amount_new: str, /// amount_new: str,
/// ) -> object: /// ) -> LayoutObj[UiResult]:
/// """Decrease or increase output amount.""" /// """Decrease or increase output amount."""
Qstr::MP_QSTR_confirm_modify_output => obj_fn_kw!(0, new_confirm_modify_output).as_obj(), Qstr::MP_QSTR_confirm_modify_output => obj_fn_kw!(0, new_confirm_modify_output).as_obj(),
@ -1842,7 +1842,7 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// address_label: str, /// address_label: str,
/// address_title: str, /// address_title: str,
/// chunkify: bool = False, /// chunkify: bool = False,
/// ) -> object: /// ) -> LayoutObj[UiResult]:
/// """Confirm output address.""" /// """Confirm output address."""
Qstr::MP_QSTR_confirm_output_address => obj_fn_kw!(0, new_confirm_output_address).as_obj(), Qstr::MP_QSTR_confirm_output_address => obj_fn_kw!(0, new_confirm_output_address).as_obj(),
@ -1850,7 +1850,7 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// *, /// *,
/// amount: str, /// amount: str,
/// amount_title: str, /// amount_title: str,
/// ) -> object: /// ) -> LayoutObj[UiResult]:
/// """Confirm output amount.""" /// """Confirm output amount."""
Qstr::MP_QSTR_confirm_output_amount => obj_fn_kw!(0, new_confirm_output_amount).as_obj(), Qstr::MP_QSTR_confirm_output_amount => obj_fn_kw!(0, new_confirm_output_amount).as_obj(),
@ -1862,7 +1862,7 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// account_label: str | None, /// account_label: str | None,
/// total_label: str, /// total_label: str,
/// fee_label: str, /// fee_label: str,
/// ) -> object: /// ) -> LayoutObj[UiResult]:
/// """Confirm summary of a transaction.""" /// """Confirm summary of a transaction."""
Qstr::MP_QSTR_confirm_total => obj_fn_kw!(0, new_confirm_total).as_obj(), Qstr::MP_QSTR_confirm_total => obj_fn_kw!(0, new_confirm_total).as_obj(),
@ -1874,11 +1874,11 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// fee_value: str, /// fee_value: str,
/// items: Iterable[Tuple[str, str]], /// items: Iterable[Tuple[str, str]],
/// cancel_cross: bool = False, /// cancel_cross: bool = False,
/// ) -> object: /// ) -> LayoutObj[UiResult]:
/// """Confirm details about altcoin transaction.""" /// """Confirm details about altcoin transaction."""
Qstr::MP_QSTR_altcoin_tx_summary => obj_fn_kw!(0, new_altcoin_tx_summary).as_obj(), Qstr::MP_QSTR_altcoin_tx_summary => obj_fn_kw!(0, new_altcoin_tx_summary).as_obj(),
/// def tutorial() -> object: /// def tutorial() -> LayoutObj[UiResult]:
/// """Show user how to interact with the device.""" /// """Show user how to interact with the device."""
Qstr::MP_QSTR_tutorial => obj_fn_kw!(0, tutorial).as_obj(), Qstr::MP_QSTR_tutorial => obj_fn_kw!(0, tutorial).as_obj(),
@ -1889,7 +1889,7 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// user_fee_change: str, /// user_fee_change: str,
/// total_fee_new: str, /// total_fee_new: str,
/// fee_rate_amount: str | None, /// fee_rate_amount: str | None,
/// ) -> object: /// ) -> LayoutObj[UiResult]:
/// """Decrease or increase transaction fee.""" /// """Decrease or increase transaction fee."""
Qstr::MP_QSTR_confirm_modify_fee => obj_fn_kw!(0, new_confirm_modify_fee).as_obj(), Qstr::MP_QSTR_confirm_modify_fee => obj_fn_kw!(0, new_confirm_modify_fee).as_obj(),
@ -1899,7 +1899,7 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// app_name: str, /// app_name: str,
/// icon_name: str | None, # unused on TR /// icon_name: str | None, # unused on TR
/// accounts: list[str | None], /// accounts: list[str | None],
/// ) -> int | object: /// ) -> LayoutObj[int | UiResult]:
/// """FIDO confirmation. /// """FIDO confirmation.
/// ///
/// Returns page index in case of confirmation and CANCELLED otherwise. /// Returns page index in case of confirmation and CANCELLED otherwise.
@ -1911,7 +1911,7 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// title: str, /// title: str,
/// verb: str, /// verb: str,
/// items: list[str], /// items: list[str],
/// ) -> object: /// ) -> LayoutObj[UiResult]:
/// """Show multiple texts, each on its own page.""" /// """Show multiple texts, each on its own page."""
Qstr::MP_QSTR_multiple_pages_texts => obj_fn_kw!(0, new_multiple_pages_texts).as_obj(), Qstr::MP_QSTR_multiple_pages_texts => obj_fn_kw!(0, new_multiple_pages_texts).as_obj(),
@ -1920,7 +1920,7 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// button: str, /// button: str,
/// warning: str, /// warning: str,
/// description: str, /// description: str,
/// ) -> object: /// ) -> LayoutObj[UiResult]:
/// """Warning modal with middle button and centered text.""" /// """Warning modal with middle button and centered text."""
Qstr::MP_QSTR_show_warning => obj_fn_kw!(0, new_show_warning).as_obj(), Qstr::MP_QSTR_show_warning => obj_fn_kw!(0, new_show_warning).as_obj(),
@ -1929,15 +1929,15 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// title: str, /// title: str,
/// description: str = "", /// description: str = "",
/// time_ms: int = 0, /// time_ms: int = 0,
/// ) -> object: /// ) -> LayoutObj[UiResult]:
/// """Info modal.""" /// """Info modal."""
Qstr::MP_QSTR_show_info => obj_fn_kw!(0, new_show_info).as_obj(), Qstr::MP_QSTR_show_info => obj_fn_kw!(0, new_show_info).as_obj(),
/// def show_passphrase() -> object: /// def show_passphrase() -> LayoutObj[UiResult]:
/// """Show passphrase on host dialog.""" /// """Show passphrase on host dialog."""
Qstr::MP_QSTR_show_passphrase => obj_fn_0!(new_show_passphrase).as_obj(), Qstr::MP_QSTR_show_passphrase => obj_fn_0!(new_show_passphrase).as_obj(),
/// def show_mismatch(*, title: str) -> object: /// def show_mismatch(*, title: str) -> LayoutObj[UiResult]:
/// """Warning modal, receiving address mismatch.""" /// """Warning modal, receiving address mismatch."""
Qstr::MP_QSTR_show_mismatch => obj_fn_kw!(0, new_show_mismatch).as_obj(), Qstr::MP_QSTR_show_mismatch => obj_fn_kw!(0, new_show_mismatch).as_obj(),
@ -1948,7 +1948,7 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// info_button: str, # unused on TR /// info_button: str, # unused on TR
/// items: Iterable[Tuple[int, str]], /// items: Iterable[Tuple[int, str]],
/// verb_cancel: str | None = None, /// verb_cancel: str | None = None,
/// ) -> object: /// ) -> LayoutObj[UiResult]:
/// """Confirm given items but with third button. Always single page /// """Confirm given items but with third button. Always single page
/// without scrolling.""" /// without scrolling."""
Qstr::MP_QSTR_confirm_with_info => obj_fn_kw!(0, new_confirm_with_info).as_obj(), Qstr::MP_QSTR_confirm_with_info => obj_fn_kw!(0, new_confirm_with_info).as_obj(),
@ -1967,7 +1967,7 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// *, /// *,
/// max_rounds: str, /// max_rounds: str,
/// max_feerate: str, /// max_feerate: str,
/// ) -> object: /// ) -> LayoutObj[UiResult]:
/// """Confirm coinjoin authorization.""" /// """Confirm coinjoin authorization."""
Qstr::MP_QSTR_confirm_coinjoin => obj_fn_kw!(0, new_confirm_coinjoin).as_obj(), Qstr::MP_QSTR_confirm_coinjoin => obj_fn_kw!(0, new_confirm_coinjoin).as_obj(),
@ -1977,7 +1977,7 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// subprompt: str, /// subprompt: str,
/// allow_cancel: bool = True, # unused on TR /// allow_cancel: bool = True, # unused on TR
/// wrong_pin: bool = False, # unused on TR /// wrong_pin: bool = False, # unused on TR
/// ) -> str | object: /// ) -> LayoutObj[str | UiResult]:
/// """Request pin on device.""" /// """Request pin on device."""
Qstr::MP_QSTR_request_pin => obj_fn_kw!(0, new_request_pin).as_obj(), Qstr::MP_QSTR_request_pin => obj_fn_kw!(0, new_request_pin).as_obj(),
@ -1985,7 +1985,7 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// *, /// *,
/// prompt: str, /// prompt: str,
/// max_len: int, # unused on TR /// max_len: int, # unused on TR
/// ) -> str | object: /// ) -> LayoutObj[str | UiResult]:
/// """Get passphrase.""" /// """Get passphrase."""
Qstr::MP_QSTR_request_passphrase => obj_fn_kw!(0, new_request_passphrase).as_obj(), Qstr::MP_QSTR_request_passphrase => obj_fn_kw!(0, new_request_passphrase).as_obj(),
@ -1994,7 +1994,7 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// prompt: str, /// prompt: str,
/// prefill_word: str, /// prefill_word: str,
/// can_go_back: bool, /// can_go_back: bool,
/// ) -> str: /// ) -> LayoutObj[str]:
/// """Get recovery word for BIP39.""" /// """Get recovery word for BIP39."""
Qstr::MP_QSTR_request_bip39 => obj_fn_kw!(0, new_request_bip39).as_obj(), Qstr::MP_QSTR_request_bip39 => obj_fn_kw!(0, new_request_bip39).as_obj(),
@ -2003,7 +2003,7 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// prompt: str, /// prompt: str,
/// prefill_word: str, /// prefill_word: str,
/// can_go_back: bool, /// can_go_back: bool,
/// ) -> str: /// ) -> LayoutObj[str]:
/// """SLIP39 word input keyboard.""" /// """SLIP39 word input keyboard."""
Qstr::MP_QSTR_request_slip39 => obj_fn_kw!(0, new_request_slip39).as_obj(), Qstr::MP_QSTR_request_slip39 => obj_fn_kw!(0, new_request_slip39).as_obj(),
@ -2012,7 +2012,7 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// title: str, # unused on TR /// title: str, # unused on TR
/// description: str, /// description: str,
/// words: Iterable[str], /// words: Iterable[str],
/// ) -> int: /// ) -> LayoutObj[int]:
/// """Select mnemonic word from three possibilities - seed check after backup. The /// """Select mnemonic word from three possibilities - seed check after backup. The
/// iterable must be of exact size. Returns index in range `0..3`.""" /// iterable must be of exact size. Returns index in range `0..3`."""
Qstr::MP_QSTR_select_word => obj_fn_kw!(0, new_select_word).as_obj(), Qstr::MP_QSTR_select_word => obj_fn_kw!(0, new_select_word).as_obj(),
@ -2020,7 +2020,7 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// def show_share_words( /// def show_share_words(
/// *, /// *,
/// share_words: Iterable[str], /// share_words: Iterable[str],
/// ) -> object: /// ) -> LayoutObj[UiResult]:
/// """Shows a backup seed.""" /// """Shows a backup seed."""
Qstr::MP_QSTR_show_share_words => obj_fn_kw!(0, new_show_share_words).as_obj(), Qstr::MP_QSTR_show_share_words => obj_fn_kw!(0, new_show_share_words).as_obj(),
@ -2031,7 +2031,7 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// min_count: int, /// min_count: int,
/// max_count: int, /// max_count: int,
/// description: Callable[[int], str] | None = None, # unused on TR /// description: Callable[[int], str] | None = None, # unused on TR
/// ) -> object: /// ) -> LayoutObj[tuple[UiResult, int]]:
/// """Number input with + and - buttons, description, and info button.""" /// """Number input with + and - buttons, description, and info button."""
Qstr::MP_QSTR_request_number => obj_fn_kw!(0, new_request_number).as_obj(), Qstr::MP_QSTR_request_number => obj_fn_kw!(0, new_request_number).as_obj(),
@ -2041,7 +2041,7 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// items: Iterable[str], /// items: Iterable[str],
/// active: int, /// active: int,
/// button: str, /// button: str,
/// ) -> object: /// ) -> LayoutObj[UiResult]:
/// """Checklist of backup steps. Active index is highlighted, previous items have check /// """Checklist of backup steps. Active index is highlighted, previous items have check
/// mark next to them.""" /// mark next to them."""
Qstr::MP_QSTR_show_checklist => obj_fn_kw!(0, new_show_checklist).as_obj(), Qstr::MP_QSTR_show_checklist => obj_fn_kw!(0, new_show_checklist).as_obj(),
@ -2054,7 +2054,7 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// dry_run: bool, /// dry_run: bool,
/// info_button: bool, # unused on TR /// info_button: bool, # unused on TR
/// show_info: bool, /// show_info: bool,
/// ) -> object: /// ) -> LayoutObj[UiResult]:
/// """Device recovery homescreen.""" /// """Device recovery homescreen."""
Qstr::MP_QSTR_confirm_recovery => obj_fn_kw!(0, new_confirm_recovery).as_obj(), Qstr::MP_QSTR_confirm_recovery => obj_fn_kw!(0, new_confirm_recovery).as_obj(),
@ -2062,13 +2062,14 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// *, /// *,
/// dry_run: bool, # unused on TR /// dry_run: bool, # unused on TR
/// ) -> int | str: # TR returns str /// ) -> int | str: # TR returns str
/// ) -> LayoutObj[int | str]:
/// """Select mnemonic word count from (12, 18, 20, 24, 33).""" /// """Select mnemonic word count from (12, 18, 20, 24, 33)."""
Qstr::MP_QSTR_select_word_count => obj_fn_kw!(0, new_select_word_count).as_obj(), Qstr::MP_QSTR_select_word_count => obj_fn_kw!(0, new_select_word_count).as_obj(),
/// def show_group_share_success( /// def show_group_share_success(
/// *, /// *,
/// lines: Iterable[str], /// lines: Iterable[str],
/// ) -> int: /// ) -> LayoutObj[int]:
/// """Shown after successfully finishing a group.""" /// """Shown after successfully finishing a group."""
Qstr::MP_QSTR_show_group_share_success => obj_fn_kw!(0, new_show_group_share_success).as_obj(), Qstr::MP_QSTR_show_group_share_success => obj_fn_kw!(0, new_show_group_share_success).as_obj(),
@ -2077,7 +2078,7 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// title: str, /// title: str,
/// indeterminate: bool = False, /// indeterminate: bool = False,
/// description: str = "", /// description: str = "",
/// ) -> object: /// ) -> LayoutObj[UiResult]:
/// """Show progress loader. Please note that the number of lines reserved on screen for /// """Show progress loader. Please note that the number of lines reserved on screen for
/// description is determined at construction time. If you want multiline descriptions /// description is determined at construction time. If you want multiline descriptions
/// make sure the initial description has at least that amount of lines.""" /// make sure the initial description has at least that amount of lines."""
@ -2089,7 +2090,7 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// indeterminate: bool = False, /// indeterminate: bool = False,
/// time_ms: int = 0, /// time_ms: int = 0,
/// skip_first_paint: bool = False, /// skip_first_paint: bool = False,
/// ) -> object: /// ) -> LayoutObj[UiResult]:
/// """Show progress loader for coinjoin. Returns CANCELLED after a specified time when /// """Show progress loader for coinjoin. Returns CANCELLED after a specified time when
/// time_ms timeout is passed.""" /// time_ms timeout is passed."""
Qstr::MP_QSTR_show_progress_coinjoin => obj_fn_kw!(0, new_show_progress_coinjoin).as_obj(), Qstr::MP_QSTR_show_progress_coinjoin => obj_fn_kw!(0, new_show_progress_coinjoin).as_obj(),
@ -2101,7 +2102,7 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// notification: str | None, /// notification: str | None,
/// notification_level: int = 0, /// notification_level: int = 0,
/// skip_first_paint: bool, /// skip_first_paint: bool,
/// ) -> CANCELLED: /// ) -> LayoutObj[UiResult]:
/// """Idle homescreen.""" /// """Idle homescreen."""
Qstr::MP_QSTR_show_homescreen => obj_fn_kw!(0, new_show_homescreen).as_obj(), Qstr::MP_QSTR_show_homescreen => obj_fn_kw!(0, new_show_homescreen).as_obj(),
@ -2111,7 +2112,7 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// bootscreen: bool, /// bootscreen: bool,
/// skip_first_paint: bool, /// skip_first_paint: bool,
/// coinjoin_authorized: bool = False, /// coinjoin_authorized: bool = False,
/// ) -> CANCELLED: /// ) -> LayoutObj[UiResult]:
/// """Homescreen for locked device.""" /// """Homescreen for locked device."""
Qstr::MP_QSTR_show_lockscreen => obj_fn_kw!(0, new_show_lockscreen).as_obj(), Qstr::MP_QSTR_show_lockscreen => obj_fn_kw!(0, new_show_lockscreen).as_obj(),

View File

@ -259,7 +259,7 @@ where
let value = self.value().try_into()?; let value = self.value().try_into()?;
match msg { match msg {
NumberInputDialogMsg::Selected => Ok((CONFIRMED.as_obj(), value).try_into()?), NumberInputDialogMsg::Selected => Ok((CONFIRMED.as_obj(), value).try_into()?),
NumberInputDialogMsg::InfoRequested => Ok((CANCELLED.as_obj(), value).try_into()?), NumberInputDialogMsg::InfoRequested => Ok((INFO.as_obj(), value).try_into()?),
} }
} }
} }
@ -1684,15 +1684,86 @@ extern "C" fn new_show_wait_text(message: Obj) -> Obj {
#[no_mangle] #[no_mangle]
pub static mp_module_trezorui2: Module = obj_module! { pub static mp_module_trezorui2: Module = obj_module! {
/// from trezor import utils
///
/// T = TypeVar("T")
///
/// class LayoutObj(Generic[T]):
/// """Representation of a Rust-based layout object.
/// see `trezor::ui::layout::obj::LayoutObj`.
/// """
///
/// def attach_timer_fn(self, fn: Callable[[int, int], None]) -> None:
/// """Attach a timer setter function.
///
/// The layout object can call the timer setter with two arguments,
/// `token` and `deadline`. When `deadline` is reached, the layout object
/// expects a callback to `self.timer(token)`.
/// """
///
/// if utils.USE_TOUCH:
/// def touch_event(self, event: int, x: int, y: int) -> T | None:
/// """Receive a touch event `event` at coordinates `x`, `y`."""
///
/// if utils.USE_BUTTON:
/// def button_event(self, event: int, button: int) -> T | None:
/// """Receive a button event `event` for button `button`."""
///
/// def progress_event(self, value: int, description: str) -> T | None:
/// """Receive a progress event."""
///
/// def usb_event(self, connected: bool) -> T | None:
/// """Receive a USB connect/disconnect event."""
///
/// def timer(self, token: int) -> T | None:
/// """Callback for the timer set by `attach_timer_fn`.
///
/// This function should be called by the executor after the corresponding
/// deadline is reached.
/// """
///
/// def paint(self) -> bool:
/// """Paint the layout object on screen.
///
/// Will only paint updated parts of the layout as required.
/// Returns True if any painting actually happened.
/// """
///
/// def request_complete_repaint(self) -> None:
/// """Request a complete repaint of the screen.
///
/// Does not repaint the screen, a subsequent call to `paint()` is required.
/// """
///
/// if __debug__:
/// def trace(self, tracer: Callable[[str], None]) -> None:
/// """Generate a JSON trace of the layout object.
///
/// The JSON can be emitted as a sequence of calls to `tracer`, each of
/// which is not necessarily a valid JSON chunk. The caller must
/// reassemble the chunks to get a sensible result.
/// """
///
/// def bounds(self) -> None:
/// """Paint bounds of individual components on screen."""
///
/// def page_count(self) -> int:
/// """Return the number of pages in the layout object."""
///
/// class UiResult:
/// """Result of a UI operation."""
/// pass
///
/// mock:global
Qstr::MP_QSTR___name__ => Qstr::MP_QSTR_trezorui2.to_obj(), Qstr::MP_QSTR___name__ => Qstr::MP_QSTR_trezorui2.to_obj(),
/// CONFIRMED: object /// CONFIRMED: UiResult
Qstr::MP_QSTR_CONFIRMED => CONFIRMED.as_obj(), Qstr::MP_QSTR_CONFIRMED => CONFIRMED.as_obj(),
/// CANCELLED: object /// CANCELLED: UiResult
Qstr::MP_QSTR_CANCELLED => CANCELLED.as_obj(), Qstr::MP_QSTR_CANCELLED => CANCELLED.as_obj(),
/// INFO: object /// INFO: UiResult
Qstr::MP_QSTR_INFO => INFO.as_obj(), Qstr::MP_QSTR_INFO => INFO.as_obj(),
/// def disable_animation(disable: bool) -> None: /// def disable_animation(disable: bool) -> None:
@ -1713,7 +1784,7 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// hold: bool = False, /// hold: bool = False,
/// hold_danger: bool = False, /// hold_danger: bool = False,
/// reverse: bool = False, /// reverse: bool = False,
/// ) -> object: /// ) -> LayoutObj[UiResult]:
/// """Confirm action.""" /// """Confirm action."""
Qstr::MP_QSTR_confirm_action => obj_fn_kw!(0, new_confirm_action).as_obj(), Qstr::MP_QSTR_confirm_action => obj_fn_kw!(0, new_confirm_action).as_obj(),
@ -1722,7 +1793,7 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// title: str, /// title: str,
/// items: Iterable[str | tuple[bool, str]], /// items: Iterable[str | tuple[bool, str]],
/// verb: str | None = None, /// verb: str | None = None,
/// ) -> object: /// ) -> LayoutObj[UiResult]:
/// """Confirm formatted text that has been pre-split in python. For tuples /// """Confirm formatted text that has been pre-split in python. For tuples
/// the first component is a bool indicating whether this part is emphasized.""" /// the first component is a bool indicating whether this part is emphasized."""
Qstr::MP_QSTR_confirm_emphasized => obj_fn_kw!(0, new_confirm_emphasized).as_obj(), Qstr::MP_QSTR_confirm_emphasized => obj_fn_kw!(0, new_confirm_emphasized).as_obj(),
@ -1731,7 +1802,7 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// *, /// *,
/// title: str, /// title: str,
/// image: bytes, /// image: bytes,
/// ) -> object: /// ) -> LayoutObj[UiResult]:
/// """Confirm homescreen.""" /// """Confirm homescreen."""
Qstr::MP_QSTR_confirm_homescreen => obj_fn_kw!(0, new_confirm_homescreen).as_obj(), Qstr::MP_QSTR_confirm_homescreen => obj_fn_kw!(0, new_confirm_homescreen).as_obj(),
@ -1745,7 +1816,7 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// verb_cancel: str | None = None, /// verb_cancel: str | None = None,
/// hold: bool = False, /// hold: bool = False,
/// chunkify: bool = False, /// chunkify: bool = False,
/// ) -> object: /// ) -> LayoutObj[UiResult]:
/// """Confirm byte sequence data.""" /// """Confirm byte sequence data."""
Qstr::MP_QSTR_confirm_blob => obj_fn_kw!(0, new_confirm_blob).as_obj(), Qstr::MP_QSTR_confirm_blob => obj_fn_kw!(0, new_confirm_blob).as_obj(),
@ -1757,7 +1828,7 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// verb: str | None = "CONFIRM", /// verb: str | None = "CONFIRM",
/// extra: str | None, /// extra: str | None,
/// chunkify: bool = False, /// chunkify: bool = False,
/// ) -> object: /// ) -> LayoutObj[UiResult]:
/// """Confirm address. Similar to `confirm_blob` but has corner info button /// """Confirm address. Similar to `confirm_blob` but has corner info button
/// and allows left swipe which does the same thing as the button.""" /// and allows left swipe which does the same thing as the button."""
Qstr::MP_QSTR_confirm_address => obj_fn_kw!(0, new_confirm_address).as_obj(), Qstr::MP_QSTR_confirm_address => obj_fn_kw!(0, new_confirm_address).as_obj(),
@ -1767,7 +1838,7 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// title: str, /// title: str,
/// items: list[tuple[str | None, str | bytes | None, bool]], /// items: list[tuple[str | None, str | bytes | None, bool]],
/// hold: bool = False, /// hold: bool = False,
/// ) -> object: /// ) -> LayoutObj[UiResult]:
/// """Confirm list of key-value pairs. The third component in the tuple should be True if /// """Confirm list of key-value pairs. The third component in the tuple should be True if
/// the value is to be rendered as binary with monospace font, False otherwise.""" /// the value is to be rendered as binary with monospace font, False otherwise."""
Qstr::MP_QSTR_confirm_properties => obj_fn_kw!(0, new_confirm_properties).as_obj(), Qstr::MP_QSTR_confirm_properties => obj_fn_kw!(0, new_confirm_properties).as_obj(),
@ -1776,7 +1847,7 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// *, /// *,
/// title: str, /// title: str,
/// button: str, /// button: str,
/// ) -> object: /// ) -> LayoutObj[UiResult]:
/// """Confirm TOS before device setup.""" /// """Confirm TOS before device setup."""
Qstr::MP_QSTR_confirm_reset_device => obj_fn_kw!(0, new_confirm_reset_device).as_obj(), Qstr::MP_QSTR_confirm_reset_device => obj_fn_kw!(0, new_confirm_reset_device).as_obj(),
@ -1789,7 +1860,7 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// account: str | None, /// account: str | None,
/// path: str | None, /// path: str | None,
/// xpubs: list[tuple[str, str]], /// xpubs: list[tuple[str, str]],
/// ) -> object: /// ) -> LayoutObj[UiResult]:
/// """Show address details - QR code, account, path, cosigner xpubs.""" /// """Show address details - QR code, account, path, cosigner xpubs."""
Qstr::MP_QSTR_show_address_details => obj_fn_kw!(0, new_show_address_details).as_obj(), Qstr::MP_QSTR_show_address_details => obj_fn_kw!(0, new_show_address_details).as_obj(),
@ -1799,7 +1870,7 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// items: Iterable[Tuple[str, str]], /// items: Iterable[Tuple[str, str]],
/// horizontal: bool = False, /// horizontal: bool = False,
/// chunkify: bool = False, /// chunkify: bool = False,
/// ) -> object: /// ) -> LayoutObj[UiResult]:
/// """Show metadata for outgoing transaction.""" /// """Show metadata for outgoing transaction."""
Qstr::MP_QSTR_show_info_with_cancel => obj_fn_kw!(0, new_show_info_with_cancel).as_obj(), Qstr::MP_QSTR_show_info_with_cancel => obj_fn_kw!(0, new_show_info_with_cancel).as_obj(),
@ -1815,7 +1886,7 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// hold: bool = False, /// hold: bool = False,
/// chunkify: bool = False, /// chunkify: bool = False,
/// text_mono: bool = True, /// text_mono: bool = True,
/// ) -> object: /// ) -> LayoutObj[UiResult]:
/// """Confirm value. Merge of confirm_total and confirm_output.""" /// """Confirm value. Merge of confirm_total and confirm_output."""
Qstr::MP_QSTR_confirm_value => obj_fn_kw!(0, new_confirm_value).as_obj(), Qstr::MP_QSTR_confirm_value => obj_fn_kw!(0, new_confirm_value).as_obj(),
@ -1825,7 +1896,7 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// items: Iterable[tuple[str, str]], /// items: Iterable[tuple[str, str]],
/// info_button: bool = False, /// info_button: bool = False,
/// cancel_arrow: bool = False, /// cancel_arrow: bool = False,
/// ) -> object: /// ) -> LayoutObj[UiResult]:
/// """Transaction summary. Always hold to confirm.""" /// """Transaction summary. Always hold to confirm."""
Qstr::MP_QSTR_confirm_total => obj_fn_kw!(0, new_confirm_total).as_obj(), Qstr::MP_QSTR_confirm_total => obj_fn_kw!(0, new_confirm_total).as_obj(),
@ -1834,7 +1905,7 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// sign: int, /// sign: int,
/// amount_change: str, /// amount_change: str,
/// amount_new: str, /// amount_new: str,
/// ) -> object: /// ) -> LayoutObj[UiResult]:
/// """Decrease or increase output amount.""" /// """Decrease or increase output amount."""
Qstr::MP_QSTR_confirm_modify_output => obj_fn_kw!(0, new_confirm_modify_output).as_obj(), Qstr::MP_QSTR_confirm_modify_output => obj_fn_kw!(0, new_confirm_modify_output).as_obj(),
@ -1845,7 +1916,7 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// user_fee_change: str, /// user_fee_change: str,
/// total_fee_new: str, /// total_fee_new: str,
/// fee_rate_amount: str | None, # ignored /// fee_rate_amount: str | None, # ignored
/// ) -> object: /// ) -> LayoutObj[UiResult]:
/// """Decrease or increase transaction fee.""" /// """Decrease or increase transaction fee."""
Qstr::MP_QSTR_confirm_modify_fee => obj_fn_kw!(0, new_confirm_modify_fee).as_obj(), Qstr::MP_QSTR_confirm_modify_fee => obj_fn_kw!(0, new_confirm_modify_fee).as_obj(),
@ -1855,7 +1926,7 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// app_name: str, /// app_name: str,
/// icon_name: str | None, /// icon_name: str | None,
/// accounts: list[str | None], /// accounts: list[str | None],
/// ) -> int | object: /// ) -> LayoutObj[int | UiResult]:
/// """FIDO confirmation. /// """FIDO confirmation.
/// ///
/// Returns page index in case of confirmation and CANCELLED otherwise. /// Returns page index in case of confirmation and CANCELLED otherwise.
@ -1869,7 +1940,7 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// description: str = "", /// description: str = "",
/// allow_cancel: bool = False, /// allow_cancel: bool = False,
/// time_ms: int = 0, /// time_ms: int = 0,
/// ) -> object: /// ) -> LayoutObj[UiResult]:
/// """Error modal. No buttons shown when `button` is empty string.""" /// """Error modal. No buttons shown when `button` is empty string."""
Qstr::MP_QSTR_show_error => obj_fn_kw!(0, new_show_error).as_obj(), Qstr::MP_QSTR_show_error => obj_fn_kw!(0, new_show_error).as_obj(),
@ -1881,7 +1952,7 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// description: str = "", /// description: str = "",
/// allow_cancel: bool = False, /// allow_cancel: bool = False,
/// time_ms: int = 0, /// time_ms: int = 0,
/// ) -> object: /// ) -> LayoutObj[UiResult]:
/// """Warning modal. No buttons shown when `button` is empty string.""" /// """Warning modal. No buttons shown when `button` is empty string."""
Qstr::MP_QSTR_show_warning => obj_fn_kw!(0, new_show_warning).as_obj(), Qstr::MP_QSTR_show_warning => obj_fn_kw!(0, new_show_warning).as_obj(),
@ -1892,7 +1963,7 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// description: str = "", /// description: str = "",
/// allow_cancel: bool = False, /// allow_cancel: bool = False,
/// time_ms: int = 0, /// time_ms: int = 0,
/// ) -> object: /// ) -> LayoutObj[UiResult]:
/// """Success modal. No buttons shown when `button` is empty string.""" /// """Success modal. No buttons shown when `button` is empty string."""
Qstr::MP_QSTR_show_success => obj_fn_kw!(0, new_show_success).as_obj(), Qstr::MP_QSTR_show_success => obj_fn_kw!(0, new_show_success).as_obj(),
@ -1903,11 +1974,11 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// description: str = "", /// description: str = "",
/// allow_cancel: bool = False, /// allow_cancel: bool = False,
/// time_ms: int = 0, /// time_ms: int = 0,
/// ) -> object: /// ) -> LayoutObj[UiResult]:
/// """Info modal. No buttons shown when `button` is empty string.""" /// """Info modal. No buttons shown when `button` is empty string."""
Qstr::MP_QSTR_show_info => obj_fn_kw!(0, new_show_info).as_obj(), Qstr::MP_QSTR_show_info => obj_fn_kw!(0, new_show_info).as_obj(),
/// def show_mismatch(*, title: str) -> object: /// def show_mismatch(*, title: str) -> LayoutObj[UiResult]:
/// """Warning modal, receiving address mismatch.""" /// """Warning modal, receiving address mismatch."""
Qstr::MP_QSTR_show_mismatch => obj_fn_kw!(0, new_show_mismatch).as_obj(), Qstr::MP_QSTR_show_mismatch => obj_fn_kw!(0, new_show_mismatch).as_obj(),
@ -1916,7 +1987,7 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// title: str | None, /// title: str | None,
/// description: str = "", /// description: str = "",
/// button: str = "", /// button: str = "",
/// ) -> object: /// ) -> LayoutObj[UiResult]:
/// """Simple dialog with text and one button.""" /// """Simple dialog with text and one button."""
Qstr::MP_QSTR_show_simple => obj_fn_kw!(0, new_show_simple).as_obj(), Qstr::MP_QSTR_show_simple => obj_fn_kw!(0, new_show_simple).as_obj(),
@ -1926,7 +1997,7 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// button: str, /// button: str,
/// info_button: str, /// info_button: str,
/// items: Iterable[tuple[int, str]], /// items: Iterable[tuple[int, str]],
/// ) -> object: /// ) -> LayoutObj[UiResult]:
/// """Confirm given items but with third button. Always single page /// """Confirm given items but with third button. Always single page
/// without scrolling.""" /// without scrolling."""
Qstr::MP_QSTR_confirm_with_info => obj_fn_kw!(0, new_confirm_with_info).as_obj(), Qstr::MP_QSTR_confirm_with_info => obj_fn_kw!(0, new_confirm_with_info).as_obj(),
@ -1936,7 +2007,7 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// title: str, /// title: str,
/// button: str, /// button: str,
/// items: Iterable[tuple[int, str]], /// items: Iterable[tuple[int, str]],
/// ) -> object: /// ) -> LayoutObj[UiResult]:
/// """Confirm long content with the possibility to go back from any page. /// """Confirm long content with the possibility to go back from any page.
/// Meant to be used with confirm_with_info.""" /// Meant to be used with confirm_with_info."""
Qstr::MP_QSTR_confirm_more => obj_fn_kw!(0, new_confirm_more).as_obj(), Qstr::MP_QSTR_confirm_more => obj_fn_kw!(0, new_confirm_more).as_obj(),
@ -1945,7 +2016,7 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// *, /// *,
/// max_rounds: str, /// max_rounds: str,
/// max_feerate: str, /// max_feerate: str,
/// ) -> object: /// ) -> LayoutObj[UiResult]:
/// """Confirm coinjoin authorization.""" /// """Confirm coinjoin authorization."""
Qstr::MP_QSTR_confirm_coinjoin => obj_fn_kw!(0, new_confirm_coinjoin).as_obj(), Qstr::MP_QSTR_confirm_coinjoin => obj_fn_kw!(0, new_confirm_coinjoin).as_obj(),
@ -1955,7 +2026,7 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// subprompt: str, /// subprompt: str,
/// allow_cancel: bool = True, /// allow_cancel: bool = True,
/// wrong_pin: bool = False, /// wrong_pin: bool = False,
/// ) -> str | object: /// ) -> LayoutObj[str | UiResult]:
/// """Request pin on device.""" /// """Request pin on device."""
Qstr::MP_QSTR_request_pin => obj_fn_kw!(0, new_request_pin).as_obj(), Qstr::MP_QSTR_request_pin => obj_fn_kw!(0, new_request_pin).as_obj(),
@ -1963,7 +2034,7 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// *, /// *,
/// prompt: str, /// prompt: str,
/// max_len: int, /// max_len: int,
/// ) -> str | object: /// ) -> LayoutObj[str | UiResult]:
/// """Passphrase input keyboard.""" /// """Passphrase input keyboard."""
Qstr::MP_QSTR_request_passphrase => obj_fn_kw!(0, new_request_passphrase).as_obj(), Qstr::MP_QSTR_request_passphrase => obj_fn_kw!(0, new_request_passphrase).as_obj(),
@ -1972,7 +2043,7 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// prompt: str, /// prompt: str,
/// prefill_word: str, /// prefill_word: str,
/// can_go_back: bool, /// can_go_back: bool,
/// ) -> str: /// ) -> LayoutObj[str]:
/// """BIP39 word input keyboard.""" /// """BIP39 word input keyboard."""
Qstr::MP_QSTR_request_bip39 => obj_fn_kw!(0, new_request_bip39).as_obj(), Qstr::MP_QSTR_request_bip39 => obj_fn_kw!(0, new_request_bip39).as_obj(),
@ -1981,7 +2052,7 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// prompt: str, /// prompt: str,
/// prefill_word: str, /// prefill_word: str,
/// can_go_back: bool, /// can_go_back: bool,
/// ) -> str: /// ) -> LayoutObj[str]:
/// """SLIP39 word input keyboard.""" /// """SLIP39 word input keyboard."""
Qstr::MP_QSTR_request_slip39 => obj_fn_kw!(0, new_request_slip39).as_obj(), Qstr::MP_QSTR_request_slip39 => obj_fn_kw!(0, new_request_slip39).as_obj(),
@ -1990,7 +2061,7 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// title: str, /// title: str,
/// description: str, /// description: str,
/// words: Iterable[str], /// words: Iterable[str],
/// ) -> int: /// ) -> LayoutObj[int]:
/// """Select mnemonic word from three possibilities - seed check after backup. The /// """Select mnemonic word from three possibilities - seed check after backup. The
/// iterable must be of exact size. Returns index in range `0..3`.""" /// iterable must be of exact size. Returns index in range `0..3`."""
Qstr::MP_QSTR_select_word => obj_fn_kw!(0, new_select_word).as_obj(), Qstr::MP_QSTR_select_word => obj_fn_kw!(0, new_select_word).as_obj(),
@ -1999,7 +2070,7 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// *, /// *,
/// title: str, /// title: str,
/// pages: Iterable[str], /// pages: Iterable[str],
/// ) -> object: /// ) -> LayoutObj[UiResult]:
/// """Show mnemonic for backup. Expects the words pre-divided into individual pages.""" /// """Show mnemonic for backup. Expects the words pre-divided into individual pages."""
Qstr::MP_QSTR_show_share_words => obj_fn_kw!(0, new_show_share_words).as_obj(), Qstr::MP_QSTR_show_share_words => obj_fn_kw!(0, new_show_share_words).as_obj(),
@ -2010,7 +2081,7 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// min_count: int, /// min_count: int,
/// max_count: int, /// max_count: int,
/// description: Callable[[int], str] | None = None, /// description: Callable[[int], str] | None = None,
/// ) -> object: /// ) -> LayoutObj[tuple[UiResult, int]]:
/// """Number input with + and - buttons, description, and info button.""" /// """Number input with + and - buttons, description, and info button."""
Qstr::MP_QSTR_request_number => obj_fn_kw!(0, new_request_number).as_obj(), Qstr::MP_QSTR_request_number => obj_fn_kw!(0, new_request_number).as_obj(),
@ -2020,7 +2091,7 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// items: Iterable[str], /// items: Iterable[str],
/// active: int, /// active: int,
/// button: str, /// button: str,
/// ) -> object: /// ) -> LayoutObj[UiResult]:
/// """Checklist of backup steps. Active index is highlighted, previous items have check /// """Checklist of backup steps. Active index is highlighted, previous items have check
/// mark next to them.""" /// mark next to them."""
Qstr::MP_QSTR_show_checklist => obj_fn_kw!(0, new_show_checklist).as_obj(), Qstr::MP_QSTR_show_checklist => obj_fn_kw!(0, new_show_checklist).as_obj(),
@ -2032,28 +2103,28 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// button: str, /// button: str,
/// dry_run: bool, /// dry_run: bool,
/// info_button: bool = False, /// info_button: bool = False,
/// ) -> object: /// ) -> LayoutObj[UiResult]:
/// """Device recovery homescreen.""" /// """Device recovery homescreen."""
Qstr::MP_QSTR_confirm_recovery => obj_fn_kw!(0, new_confirm_recovery).as_obj(), Qstr::MP_QSTR_confirm_recovery => obj_fn_kw!(0, new_confirm_recovery).as_obj(),
/// def select_word_count( /// def select_word_count(
/// *, /// *,
/// dry_run: bool, /// dry_run: bool,
/// ) -> int | str: # TT returns int /// ) -> LayoutObj[int | str]: # TT returns int
/// """Select mnemonic word count from (12, 18, 20, 24, 33).""" /// """Select mnemonic word count from (12, 18, 20, 24, 33)."""
Qstr::MP_QSTR_select_word_count => obj_fn_kw!(0, new_select_word_count).as_obj(), Qstr::MP_QSTR_select_word_count => obj_fn_kw!(0, new_select_word_count).as_obj(),
/// def show_group_share_success( /// def show_group_share_success(
/// *, /// *,
/// lines: Iterable[str] /// lines: Iterable[str]
/// ) -> int: /// ) -> LayoutObj[UiResult]:
/// """Shown after successfully finishing a group.""" /// """Shown after successfully finishing a group."""
Qstr::MP_QSTR_show_group_share_success => obj_fn_kw!(0, new_show_group_share_success).as_obj(), Qstr::MP_QSTR_show_group_share_success => obj_fn_kw!(0, new_show_group_share_success).as_obj(),
/// def show_remaining_shares( /// def show_remaining_shares(
/// *, /// *,
/// pages: Iterable[tuple[str, str]], /// pages: Iterable[tuple[str, str]],
/// ) -> int: /// ) -> LayoutObj[UiResult]:
/// """Shows SLIP39 state after info button is pressed on `confirm_recovery`.""" /// """Shows SLIP39 state after info button is pressed on `confirm_recovery`."""
Qstr::MP_QSTR_show_remaining_shares => obj_fn_kw!(0, new_show_remaining_shares).as_obj(), Qstr::MP_QSTR_show_remaining_shares => obj_fn_kw!(0, new_show_remaining_shares).as_obj(),
@ -2062,7 +2133,7 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// title: str, /// title: str,
/// indeterminate: bool = False, /// indeterminate: bool = False,
/// description: str = "", /// description: str = "",
/// ) -> object: /// ) -> LayoutObj[UiResult]:
/// """Show progress loader. Please note that the number of lines reserved on screen for /// """Show progress loader. Please note that the number of lines reserved on screen for
/// description is determined at construction time. If you want multiline descriptions /// description is determined at construction time. If you want multiline descriptions
/// make sure the initial description has at least that amount of lines.""" /// make sure the initial description has at least that amount of lines."""
@ -2074,7 +2145,7 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// indeterminate: bool = False, /// indeterminate: bool = False,
/// time_ms: int = 0, /// time_ms: int = 0,
/// skip_first_paint: bool = False, /// skip_first_paint: bool = False,
/// ) -> object: /// ) -> LayoutObj[UiResult]:
/// """Show progress loader for coinjoin. Returns CANCELLED after a specified time when /// """Show progress loader for coinjoin. Returns CANCELLED after a specified time when
/// time_ms timeout is passed.""" /// time_ms timeout is passed."""
Qstr::MP_QSTR_show_progress_coinjoin => obj_fn_kw!(0, new_show_progress_coinjoin).as_obj(), Qstr::MP_QSTR_show_progress_coinjoin => obj_fn_kw!(0, new_show_progress_coinjoin).as_obj(),
@ -2086,7 +2157,7 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// notification: str | None, /// notification: str | None,
/// notification_level: int = 0, /// notification_level: int = 0,
/// skip_first_paint: bool, /// skip_first_paint: bool,
/// ) -> CANCELLED: /// ) -> LayoutObj[UiResult]:
/// """Idle homescreen.""" /// """Idle homescreen."""
Qstr::MP_QSTR_show_homescreen => obj_fn_kw!(0, new_show_homescreen).as_obj(), Qstr::MP_QSTR_show_homescreen => obj_fn_kw!(0, new_show_homescreen).as_obj(),
@ -2096,7 +2167,7 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// bootscreen: bool, /// bootscreen: bool,
/// skip_first_paint: bool, /// skip_first_paint: bool,
/// coinjoin_authorized: bool = False, /// coinjoin_authorized: bool = False,
/// ) -> CANCELLED: /// ) -> LayoutObj[UiResult]:
/// """Homescreen for locked device.""" /// """Homescreen for locked device."""
Qstr::MP_QSTR_show_lockscreen => obj_fn_kw!(0, new_show_lockscreen).as_obj(), Qstr::MP_QSTR_show_lockscreen => obj_fn_kw!(0, new_show_lockscreen).as_obj(),
@ -2104,11 +2175,11 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// *, /// *,
/// description: str, /// description: str,
/// fingerprint: str, /// fingerprint: str,
/// ) -> None: /// ) -> LayoutObj[UiResult]:
/// """Ask whether to update firmware, optionally show fingerprint. Shared with bootloader.""" /// """Ask whether to update firmware, optionally show fingerprint. Shared with bootloader."""
Qstr::MP_QSTR_confirm_firmware_update => obj_fn_kw!(0, new_confirm_firmware_update).as_obj(), Qstr::MP_QSTR_confirm_firmware_update => obj_fn_kw!(0, new_confirm_firmware_update).as_obj(),
/// def show_wait_text(/, message: str) -> None: /// def show_wait_text(/, message: str) -> LayoutObj[None]:
/// """Show single-line text in the middle of the screen.""" /// """Show single-line text in the middle of the screen."""
Qstr::MP_QSTR_show_wait_text => obj_fn_1!(new_show_wait_text).as_obj(), Qstr::MP_QSTR_show_wait_text => obj_fn_1!(new_show_wait_text).as_obj(),
}; };

View File

@ -1,7 +1,7 @@
from typing import * from typing import *
CONFIRMED: object CONFIRMED: UiResult
CANCELLED: object CANCELLED: UiResult
INFO: object INFO: UiResult
# rust/src/ui/model_tr/layout.rs # rust/src/ui/model_tr/layout.rs
@ -25,7 +25,7 @@ def confirm_action(
hold: bool = False, hold: bool = False,
hold_danger: bool = False, # unused on TR hold_danger: bool = False, # unused on TR
reverse: bool = False, reverse: bool = False,
) -> object: ) -> LayoutObj[UiResult]:
"""Confirm action.""" """Confirm action."""
@ -49,7 +49,7 @@ def confirm_blob(
verb_cancel: str | None = None, verb_cancel: str | None = None,
hold: bool = False, hold: bool = False,
chunkify: bool = False, chunkify: bool = False,
) -> object: ) -> LayoutObj[UiResult]:
"""Confirm byte sequence data.""" """Confirm byte sequence data."""
@ -62,7 +62,7 @@ def confirm_address(
extra: str | None, # unused on TR extra: str | None, # unused on TR
verb: str = "CONFIRM", verb: str = "CONFIRM",
chunkify: bool = False, chunkify: bool = False,
) -> object: ) -> LayoutObj[UiResult]:
"""Confirm address.""" """Confirm address."""
@ -72,7 +72,7 @@ def confirm_properties(
title: str, title: str,
items: list[tuple[str | None, str | bytes | None, bool]], items: list[tuple[str | None, str | bytes | None, bool]],
hold: bool = False, hold: bool = False,
) -> object: ) -> LayoutObj[UiResult]:
"""Confirm list of key-value pairs. The third component in the tuple should be True if """Confirm list of key-value pairs. The third component in the tuple should be True if
the value is to be rendered as binary with monospace font, False otherwise. the value is to be rendered as binary with monospace font, False otherwise.
This only concerns the text style, you need to decode the value to UTF-8 in python.""" This only concerns the text style, you need to decode the value to UTF-8 in python."""
@ -83,12 +83,12 @@ def confirm_reset_device(
*, *,
title: str, title: str,
button: str, button: str,
) -> object: ) -> LayoutObj[UiResult]:
"""Confirm TOS before device setup.""" """Confirm TOS before device setup."""
# rust/src/ui/model_tr/layout.rs # rust/src/ui/model_tr/layout.rs
def confirm_backup() -> object: def confirm_backup() -> LayoutObj[UiResult]:
"""Strongly recommend user to do backup.""" """Strongly recommend user to do backup."""
@ -100,7 +100,7 @@ def show_address_details(
account: str | None, account: str | None,
path: str | None, path: str | None,
xpubs: list[tuple[str, str]], xpubs: list[tuple[str, str]],
) -> object: ) -> LayoutObj[UiResult]:
"""Show address details - QR code, account, path, cosigner xpubs.""" """Show address details - QR code, account, path, cosigner xpubs."""
@ -112,7 +112,7 @@ def confirm_value(
value: str, value: str,
verb: str | None = None, verb: str | None = None,
hold: bool = False, hold: bool = False,
) -> object: ) -> LayoutObj[UiResult]:
"""Confirm value.""" """Confirm value."""
@ -121,7 +121,7 @@ def confirm_joint_total(
*, *,
spending_amount: str, spending_amount: str,
total_amount: str, total_amount: str,
) -> object: ) -> LayoutObj[UiResult]:
"""Confirm total if there are external inputs.""" """Confirm total if there are external inputs."""
@ -131,7 +131,7 @@ def confirm_modify_output(
sign: int, sign: int,
amount_change: str, amount_change: str,
amount_new: str, amount_new: str,
) -> object: ) -> LayoutObj[UiResult]:
"""Decrease or increase output amount.""" """Decrease or increase output amount."""
@ -142,7 +142,7 @@ def confirm_output_address(
address_label: str, address_label: str,
address_title: str, address_title: str,
chunkify: bool = False, chunkify: bool = False,
) -> object: ) -> LayoutObj[UiResult]:
"""Confirm output address.""" """Confirm output address."""
@ -151,7 +151,7 @@ def confirm_output_amount(
*, *,
amount: str, amount: str,
amount_title: str, amount_title: str,
) -> object: ) -> LayoutObj[UiResult]:
"""Confirm output amount.""" """Confirm output amount."""
@ -164,7 +164,7 @@ def confirm_total(
account_label: str | None, account_label: str | None,
total_label: str, total_label: str,
fee_label: str, fee_label: str,
) -> object: ) -> LayoutObj[UiResult]:
"""Confirm summary of a transaction.""" """Confirm summary of a transaction."""
@ -177,12 +177,12 @@ def altcoin_tx_summary(
fee_value: str, fee_value: str,
items: Iterable[Tuple[str, str]], items: Iterable[Tuple[str, str]],
cancel_cross: bool = False, cancel_cross: bool = False,
) -> object: ) -> LayoutObj[UiResult]:
"""Confirm details about altcoin transaction.""" """Confirm details about altcoin transaction."""
# rust/src/ui/model_tr/layout.rs # rust/src/ui/model_tr/layout.rs
def tutorial() -> object: def tutorial() -> LayoutObj[UiResult]:
"""Show user how to interact with the device.""" """Show user how to interact with the device."""
@ -194,7 +194,7 @@ def confirm_modify_fee(
user_fee_change: str, user_fee_change: str,
total_fee_new: str, total_fee_new: str,
fee_rate_amount: str | None, fee_rate_amount: str | None,
) -> object: ) -> LayoutObj[UiResult]:
"""Decrease or increase transaction fee.""" """Decrease or increase transaction fee."""
@ -205,7 +205,7 @@ def confirm_fido(
app_name: str, app_name: str,
icon_name: str | None, # unused on TR icon_name: str | None, # unused on TR
accounts: list[str | None], accounts: list[str | None],
) -> int | object: ) -> LayoutObj[int | UiResult]:
"""FIDO confirmation. """FIDO confirmation.
Returns page index in case of confirmation and CANCELLED otherwise. Returns page index in case of confirmation and CANCELLED otherwise.
""" """
@ -217,7 +217,7 @@ def multiple_pages_texts(
title: str, title: str,
verb: str, verb: str,
items: list[str], items: list[str],
) -> object: ) -> LayoutObj[UiResult]:
"""Show multiple texts, each on its own page.""" """Show multiple texts, each on its own page."""
@ -227,7 +227,7 @@ def show_warning(
button: str, button: str,
warning: str, warning: str,
description: str, description: str,
) -> object: ) -> LayoutObj[UiResult]:
"""Warning modal with middle button and centered text.""" """Warning modal with middle button and centered text."""
@ -237,17 +237,17 @@ def show_info(
title: str, title: str,
description: str = "", description: str = "",
time_ms: int = 0, time_ms: int = 0,
) -> object: ) -> LayoutObj[UiResult]:
"""Info modal.""" """Info modal."""
# rust/src/ui/model_tr/layout.rs # rust/src/ui/model_tr/layout.rs
def show_passphrase() -> object: def show_passphrase() -> LayoutObj[UiResult]:
"""Show passphrase on host dialog.""" """Show passphrase on host dialog."""
# rust/src/ui/model_tr/layout.rs # rust/src/ui/model_tr/layout.rs
def show_mismatch(*, title: str) -> object: def show_mismatch(*, title: str) -> LayoutObj[UiResult]:
"""Warning modal, receiving address mismatch.""" """Warning modal, receiving address mismatch."""
@ -259,7 +259,7 @@ def confirm_with_info(
info_button: str, # unused on TR info_button: str, # unused on TR
items: Iterable[Tuple[int, str]], items: Iterable[Tuple[int, str]],
verb_cancel: str | None = None, verb_cancel: str | None = None,
) -> object: ) -> LayoutObj[UiResult]:
"""Confirm given items but with third button. Always single page """Confirm given items but with third button. Always single page
without scrolling.""" without scrolling."""
@ -280,7 +280,7 @@ def confirm_coinjoin(
*, *,
max_rounds: str, max_rounds: str,
max_feerate: str, max_feerate: str,
) -> object: ) -> LayoutObj[UiResult]:
"""Confirm coinjoin authorization.""" """Confirm coinjoin authorization."""
@ -291,7 +291,7 @@ def request_pin(
subprompt: str, subprompt: str,
allow_cancel: bool = True, # unused on TR allow_cancel: bool = True, # unused on TR
wrong_pin: bool = False, # unused on TR wrong_pin: bool = False, # unused on TR
) -> str | object: ) -> LayoutObj[str | UiResult]:
"""Request pin on device.""" """Request pin on device."""
@ -300,7 +300,7 @@ def request_passphrase(
*, *,
prompt: str, prompt: str,
max_len: int, # unused on TR max_len: int, # unused on TR
) -> str | object: ) -> LayoutObj[str | UiResult]:
"""Get passphrase.""" """Get passphrase."""
@ -310,7 +310,7 @@ def request_bip39(
prompt: str, prompt: str,
prefill_word: str, prefill_word: str,
can_go_back: bool, can_go_back: bool,
) -> str: ) -> LayoutObj[str]:
"""Get recovery word for BIP39.""" """Get recovery word for BIP39."""
@ -320,7 +320,7 @@ def request_slip39(
prompt: str, prompt: str,
prefill_word: str, prefill_word: str,
can_go_back: bool, can_go_back: bool,
) -> str: ) -> LayoutObj[str]:
"""SLIP39 word input keyboard.""" """SLIP39 word input keyboard."""
@ -330,7 +330,7 @@ def select_word(
title: str, # unused on TR title: str, # unused on TR
description: str, description: str,
words: Iterable[str], words: Iterable[str],
) -> int: ) -> LayoutObj[int]:
"""Select mnemonic word from three possibilities - seed check after backup. The """Select mnemonic word from three possibilities - seed check after backup. The
iterable must be of exact size. Returns index in range `0..3`.""" iterable must be of exact size. Returns index in range `0..3`."""
@ -339,7 +339,7 @@ def select_word(
def show_share_words( def show_share_words(
*, *,
share_words: Iterable[str], share_words: Iterable[str],
) -> object: ) -> LayoutObj[UiResult]:
"""Shows a backup seed.""" """Shows a backup seed."""
@ -351,7 +351,7 @@ def request_number(
min_count: int, min_count: int,
max_count: int, max_count: int,
description: Callable[[int], str] | None = None, # unused on TR description: Callable[[int], str] | None = None, # unused on TR
) -> object: ) -> LayoutObj[tuple[UiResult, int]]:
"""Number input with + and - buttons, description, and info button.""" """Number input with + and - buttons, description, and info button."""
@ -362,7 +362,7 @@ def show_checklist(
items: Iterable[str], items: Iterable[str],
active: int, active: int,
button: str, button: str,
) -> object: ) -> LayoutObj[UiResult]:
"""Checklist of backup steps. Active index is highlighted, previous items have check """Checklist of backup steps. Active index is highlighted, previous items have check
mark next to them.""" mark next to them."""
@ -376,7 +376,7 @@ def confirm_recovery(
dry_run: bool, dry_run: bool,
info_button: bool, # unused on TR info_button: bool, # unused on TR
show_info: bool, show_info: bool,
) -> object: ) -> LayoutObj[UiResult]:
"""Device recovery homescreen.""" """Device recovery homescreen."""
@ -385,6 +385,7 @@ def select_word_count(
*, *,
dry_run: bool, # unused on TR dry_run: bool, # unused on TR
) -> int | str: # TR returns str ) -> int | str: # TR returns str
) -> LayoutObj[int | str]:
"""Select mnemonic word count from (12, 18, 20, 24, 33).""" """Select mnemonic word count from (12, 18, 20, 24, 33)."""
@ -392,7 +393,7 @@ def select_word_count(
def show_group_share_success( def show_group_share_success(
*, *,
lines: Iterable[str], lines: Iterable[str],
) -> int: ) -> LayoutObj[int]:
"""Shown after successfully finishing a group.""" """Shown after successfully finishing a group."""
@ -402,7 +403,7 @@ def show_progress(
title: str, title: str,
indeterminate: bool = False, indeterminate: bool = False,
description: str = "", description: str = "",
) -> object: ) -> LayoutObj[UiResult]:
"""Show progress loader. Please note that the number of lines reserved on screen for """Show progress loader. Please note that the number of lines reserved on screen for
description is determined at construction time. If you want multiline descriptions description is determined at construction time. If you want multiline descriptions
make sure the initial description has at least that amount of lines.""" make sure the initial description has at least that amount of lines."""
@ -415,7 +416,7 @@ def show_progress_coinjoin(
indeterminate: bool = False, indeterminate: bool = False,
time_ms: int = 0, time_ms: int = 0,
skip_first_paint: bool = False, skip_first_paint: bool = False,
) -> object: ) -> LayoutObj[UiResult]:
"""Show progress loader for coinjoin. Returns CANCELLED after a specified time when """Show progress loader for coinjoin. Returns CANCELLED after a specified time when
time_ms timeout is passed.""" time_ms timeout is passed."""
@ -428,7 +429,7 @@ def show_homescreen(
notification: str | None, notification: str | None,
notification_level: int = 0, notification_level: int = 0,
skip_first_paint: bool, skip_first_paint: bool,
) -> CANCELLED: ) -> LayoutObj[UiResult]:
"""Idle homescreen.""" """Idle homescreen."""
@ -439,7 +440,7 @@ def show_lockscreen(
bootscreen: bool, bootscreen: bool,
skip_first_paint: bool, skip_first_paint: bool,
coinjoin_authorized: bool = False, coinjoin_authorized: bool = False,
) -> CANCELLED: ) -> LayoutObj[UiResult]:
"""Homescreen for locked device.""" """Homescreen for locked device."""
@ -455,9 +456,65 @@ def confirm_firmware_update(
# rust/src/ui/model_tr/layout.rs # rust/src/ui/model_tr/layout.rs
def show_wait_text(/, message: str) -> None: def show_wait_text(/, message: str) -> None:
"""Show single-line text in the middle of the screen.""" """Show single-line text in the middle of the screen."""
CONFIRMED: object from trezor import utils
CANCELLED: object T = TypeVar("T")
INFO: object
# rust/src/ui/model_tt/layout.rs
class LayoutObj(Generic[T]):
"""Representation of a Rust-based layout object.
see `trezor::ui::layout::obj::LayoutObj`.
"""
def attach_timer_fn(self, fn: Callable[[int, int], None]) -> None:
"""Attach a timer setter function.
The layout object can call the timer setter with two arguments,
`token` and `deadline`. When `deadline` is reached, the layout object
expects a callback to `self.timer(token)`.
"""
if utils.USE_TOUCH:
def touch_event(self, event: int, x: int, y: int) -> T | None:
"""Receive a touch event `event` at coordinates `x`, `y`."""
if utils.USE_BUTTON:
def button_event(self, event: int, button: int) -> T | None:
"""Receive a button event `event` for button `button`."""
def progress_event(self, value: int, description: str) -> T | None:
"""Receive a progress event."""
def usb_event(self, connected: bool) -> T | None:
"""Receive a USB connect/disconnect event."""
def timer(self, token: int) -> T | None:
"""Callback for the timer set by `attach_timer_fn`.
This function should be called by the executor after the corresponding
deadline is reached.
"""
def paint(self) -> bool:
"""Paint the layout object on screen.
Will only paint updated parts of the layout as required.
Returns True if any painting actually happened.
"""
def request_complete_repaint(self) -> None:
"""Request a complete repaint of the screen.
Does not repaint the screen, a subsequent call to `paint()` is required.
"""
if __debug__:
def trace(self, tracer: Callable[[str], None]) -> None:
"""Generate a JSON trace of the layout object.
The JSON can be emitted as a sequence of calls to `tracer`, each of
which is not necessarily a valid JSON chunk. The caller must
reassemble the chunks to get a sensible result.
"""
def bounds(self) -> None:
"""Paint bounds of individual components on screen."""
def page_count(self) -> int:
"""Return the number of pages in the layout object."""
# rust/src/ui/model_tt/layout.rs
class UiResult:
"""Result of a UI operation."""
pass
CONFIRMED: UiResult
CANCELLED: UiResult
INFO: UiResult
# rust/src/ui/model_tt/layout.rs # rust/src/ui/model_tt/layout.rs
@ -481,7 +538,7 @@ def confirm_action(
hold: bool = False, hold: bool = False,
hold_danger: bool = False, hold_danger: bool = False,
reverse: bool = False, reverse: bool = False,
) -> object: ) -> LayoutObj[UiResult]:
"""Confirm action.""" """Confirm action."""
@ -491,7 +548,7 @@ def confirm_emphasized(
title: str, title: str,
items: Iterable[str | tuple[bool, str]], items: Iterable[str | tuple[bool, str]],
verb: str | None = None, verb: str | None = None,
) -> object: ) -> LayoutObj[UiResult]:
"""Confirm formatted text that has been pre-split in python. For tuples """Confirm formatted text that has been pre-split in python. For tuples
the first component is a bool indicating whether this part is emphasized.""" the first component is a bool indicating whether this part is emphasized."""
@ -501,7 +558,7 @@ def confirm_homescreen(
*, *,
title: str, title: str,
image: bytes, image: bytes,
) -> object: ) -> LayoutObj[UiResult]:
"""Confirm homescreen.""" """Confirm homescreen."""
@ -516,7 +573,7 @@ def confirm_blob(
verb_cancel: str | None = None, verb_cancel: str | None = None,
hold: bool = False, hold: bool = False,
chunkify: bool = False, chunkify: bool = False,
) -> object: ) -> LayoutObj[UiResult]:
"""Confirm byte sequence data.""" """Confirm byte sequence data."""
@ -529,7 +586,7 @@ def confirm_address(
verb: str | None = "CONFIRM", verb: str | None = "CONFIRM",
extra: str | None, extra: str | None,
chunkify: bool = False, chunkify: bool = False,
) -> object: ) -> LayoutObj[UiResult]:
"""Confirm address. Similar to `confirm_blob` but has corner info button """Confirm address. Similar to `confirm_blob` but has corner info button
and allows left swipe which does the same thing as the button.""" and allows left swipe which does the same thing as the button."""
@ -540,7 +597,7 @@ def confirm_properties(
title: str, title: str,
items: list[tuple[str | None, str | bytes | None, bool]], items: list[tuple[str | None, str | bytes | None, bool]],
hold: bool = False, hold: bool = False,
) -> object: ) -> LayoutObj[UiResult]:
"""Confirm list of key-value pairs. The third component in the tuple should be True if """Confirm list of key-value pairs. The third component in the tuple should be True if
the value is to be rendered as binary with monospace font, False otherwise.""" the value is to be rendered as binary with monospace font, False otherwise."""
@ -550,7 +607,7 @@ def confirm_reset_device(
*, *,
title: str, title: str,
button: str, button: str,
) -> object: ) -> LayoutObj[UiResult]:
"""Confirm TOS before device setup.""" """Confirm TOS before device setup."""
@ -564,7 +621,7 @@ def show_address_details(
account: str | None, account: str | None,
path: str | None, path: str | None,
xpubs: list[tuple[str, str]], xpubs: list[tuple[str, str]],
) -> object: ) -> LayoutObj[UiResult]:
"""Show address details - QR code, account, path, cosigner xpubs.""" """Show address details - QR code, account, path, cosigner xpubs."""
@ -575,7 +632,7 @@ def show_info_with_cancel(
items: Iterable[Tuple[str, str]], items: Iterable[Tuple[str, str]],
horizontal: bool = False, horizontal: bool = False,
chunkify: bool = False, chunkify: bool = False,
) -> object: ) -> LayoutObj[UiResult]:
"""Show metadata for outgoing transaction.""" """Show metadata for outgoing transaction."""
@ -592,7 +649,7 @@ def confirm_value(
hold: bool = False, hold: bool = False,
chunkify: bool = False, chunkify: bool = False,
text_mono: bool = True, text_mono: bool = True,
) -> object: ) -> LayoutObj[UiResult]:
"""Confirm value. Merge of confirm_total and confirm_output.""" """Confirm value. Merge of confirm_total and confirm_output."""
@ -603,7 +660,7 @@ def confirm_total(
items: Iterable[tuple[str, str]], items: Iterable[tuple[str, str]],
info_button: bool = False, info_button: bool = False,
cancel_arrow: bool = False, cancel_arrow: bool = False,
) -> object: ) -> LayoutObj[UiResult]:
"""Transaction summary. Always hold to confirm.""" """Transaction summary. Always hold to confirm."""
@ -613,7 +670,7 @@ def confirm_modify_output(
sign: int, sign: int,
amount_change: str, amount_change: str,
amount_new: str, amount_new: str,
) -> object: ) -> LayoutObj[UiResult]:
"""Decrease or increase output amount.""" """Decrease or increase output amount."""
@ -625,7 +682,7 @@ def confirm_modify_fee(
user_fee_change: str, user_fee_change: str,
total_fee_new: str, total_fee_new: str,
fee_rate_amount: str | None, # ignored fee_rate_amount: str | None, # ignored
) -> object: ) -> LayoutObj[UiResult]:
"""Decrease or increase transaction fee.""" """Decrease or increase transaction fee."""
@ -636,7 +693,7 @@ def confirm_fido(
app_name: str, app_name: str,
icon_name: str | None, icon_name: str | None,
accounts: list[str | None], accounts: list[str | None],
) -> int | object: ) -> LayoutObj[int | UiResult]:
"""FIDO confirmation. """FIDO confirmation.
Returns page index in case of confirmation and CANCELLED otherwise. Returns page index in case of confirmation and CANCELLED otherwise.
""" """
@ -650,7 +707,7 @@ def show_error(
description: str = "", description: str = "",
allow_cancel: bool = False, allow_cancel: bool = False,
time_ms: int = 0, time_ms: int = 0,
) -> object: ) -> LayoutObj[UiResult]:
"""Error modal. No buttons shown when `button` is empty string.""" """Error modal. No buttons shown when `button` is empty string."""
@ -663,7 +720,7 @@ def show_warning(
description: str = "", description: str = "",
allow_cancel: bool = False, allow_cancel: bool = False,
time_ms: int = 0, time_ms: int = 0,
) -> object: ) -> LayoutObj[UiResult]:
"""Warning modal. No buttons shown when `button` is empty string.""" """Warning modal. No buttons shown when `button` is empty string."""
@ -675,7 +732,7 @@ def show_success(
description: str = "", description: str = "",
allow_cancel: bool = False, allow_cancel: bool = False,
time_ms: int = 0, time_ms: int = 0,
) -> object: ) -> LayoutObj[UiResult]:
"""Success modal. No buttons shown when `button` is empty string.""" """Success modal. No buttons shown when `button` is empty string."""
@ -687,12 +744,12 @@ def show_info(
description: str = "", description: str = "",
allow_cancel: bool = False, allow_cancel: bool = False,
time_ms: int = 0, time_ms: int = 0,
) -> object: ) -> LayoutObj[UiResult]:
"""Info modal. No buttons shown when `button` is empty string.""" """Info modal. No buttons shown when `button` is empty string."""
# rust/src/ui/model_tt/layout.rs # rust/src/ui/model_tt/layout.rs
def show_mismatch(*, title: str) -> object: def show_mismatch(*, title: str) -> LayoutObj[UiResult]:
"""Warning modal, receiving address mismatch.""" """Warning modal, receiving address mismatch."""
@ -702,7 +759,7 @@ def show_simple(
title: str | None, title: str | None,
description: str = "", description: str = "",
button: str = "", button: str = "",
) -> object: ) -> LayoutObj[UiResult]:
"""Simple dialog with text and one button.""" """Simple dialog with text and one button."""
@ -713,7 +770,7 @@ def confirm_with_info(
button: str, button: str,
info_button: str, info_button: str,
items: Iterable[tuple[int, str]], items: Iterable[tuple[int, str]],
) -> object: ) -> LayoutObj[UiResult]:
"""Confirm given items but with third button. Always single page """Confirm given items but with third button. Always single page
without scrolling.""" without scrolling."""
@ -724,7 +781,7 @@ def confirm_more(
title: str, title: str,
button: str, button: str,
items: Iterable[tuple[int, str]], items: Iterable[tuple[int, str]],
) -> object: ) -> LayoutObj[UiResult]:
"""Confirm long content with the possibility to go back from any page. """Confirm long content with the possibility to go back from any page.
Meant to be used with confirm_with_info.""" Meant to be used with confirm_with_info."""
@ -734,7 +791,7 @@ def confirm_coinjoin(
*, *,
max_rounds: str, max_rounds: str,
max_feerate: str, max_feerate: str,
) -> object: ) -> LayoutObj[UiResult]:
"""Confirm coinjoin authorization.""" """Confirm coinjoin authorization."""
@ -745,7 +802,7 @@ def request_pin(
subprompt: str, subprompt: str,
allow_cancel: bool = True, allow_cancel: bool = True,
wrong_pin: bool = False, wrong_pin: bool = False,
) -> str | object: ) -> LayoutObj[str | UiResult]:
"""Request pin on device.""" """Request pin on device."""
@ -754,7 +811,7 @@ def request_passphrase(
*, *,
prompt: str, prompt: str,
max_len: int, max_len: int,
) -> str | object: ) -> LayoutObj[str | UiResult]:
"""Passphrase input keyboard.""" """Passphrase input keyboard."""
@ -764,7 +821,7 @@ def request_bip39(
prompt: str, prompt: str,
prefill_word: str, prefill_word: str,
can_go_back: bool, can_go_back: bool,
) -> str: ) -> LayoutObj[str]:
"""BIP39 word input keyboard.""" """BIP39 word input keyboard."""
@ -774,7 +831,7 @@ def request_slip39(
prompt: str, prompt: str,
prefill_word: str, prefill_word: str,
can_go_back: bool, can_go_back: bool,
) -> str: ) -> LayoutObj[str]:
"""SLIP39 word input keyboard.""" """SLIP39 word input keyboard."""
@ -784,7 +841,7 @@ def select_word(
title: str, title: str,
description: str, description: str,
words: Iterable[str], words: Iterable[str],
) -> int: ) -> LayoutObj[int]:
"""Select mnemonic word from three possibilities - seed check after backup. The """Select mnemonic word from three possibilities - seed check after backup. The
iterable must be of exact size. Returns index in range `0..3`.""" iterable must be of exact size. Returns index in range `0..3`."""
@ -794,7 +851,7 @@ def show_share_words(
*, *,
title: str, title: str,
pages: Iterable[str], pages: Iterable[str],
) -> object: ) -> LayoutObj[UiResult]:
"""Show mnemonic for backup. Expects the words pre-divided into individual pages.""" """Show mnemonic for backup. Expects the words pre-divided into individual pages."""
@ -806,7 +863,7 @@ def request_number(
min_count: int, min_count: int,
max_count: int, max_count: int,
description: Callable[[int], str] | None = None, description: Callable[[int], str] | None = None,
) -> object: ) -> LayoutObj[tuple[UiResult, int]]:
"""Number input with + and - buttons, description, and info button.""" """Number input with + and - buttons, description, and info button."""
@ -817,7 +874,7 @@ def show_checklist(
items: Iterable[str], items: Iterable[str],
active: int, active: int,
button: str, button: str,
) -> object: ) -> LayoutObj[UiResult]:
"""Checklist of backup steps. Active index is highlighted, previous items have check """Checklist of backup steps. Active index is highlighted, previous items have check
mark next to them.""" mark next to them."""
@ -830,7 +887,7 @@ def confirm_recovery(
button: str, button: str,
dry_run: bool, dry_run: bool,
info_button: bool = False, info_button: bool = False,
) -> object: ) -> LayoutObj[UiResult]:
"""Device recovery homescreen.""" """Device recovery homescreen."""
@ -838,7 +895,7 @@ def confirm_recovery(
def select_word_count( def select_word_count(
*, *,
dry_run: bool, dry_run: bool,
) -> int | str: # TT returns int ) -> LayoutObj[int | str]: # TT returns int
"""Select mnemonic word count from (12, 18, 20, 24, 33).""" """Select mnemonic word count from (12, 18, 20, 24, 33)."""
@ -846,7 +903,7 @@ def select_word_count(
def show_group_share_success( def show_group_share_success(
*, *,
lines: Iterable[str] lines: Iterable[str]
) -> int: ) -> LayoutObj[UiResult]:
"""Shown after successfully finishing a group.""" """Shown after successfully finishing a group."""
@ -854,7 +911,7 @@ def show_group_share_success(
def show_remaining_shares( def show_remaining_shares(
*, *,
pages: Iterable[tuple[str, str]], pages: Iterable[tuple[str, str]],
) -> int: ) -> LayoutObj[UiResult]:
"""Shows SLIP39 state after info button is pressed on `confirm_recovery`.""" """Shows SLIP39 state after info button is pressed on `confirm_recovery`."""
@ -864,7 +921,7 @@ def show_progress(
title: str, title: str,
indeterminate: bool = False, indeterminate: bool = False,
description: str = "", description: str = "",
) -> object: ) -> LayoutObj[UiResult]:
"""Show progress loader. Please note that the number of lines reserved on screen for """Show progress loader. Please note that the number of lines reserved on screen for
description is determined at construction time. If you want multiline descriptions description is determined at construction time. If you want multiline descriptions
make sure the initial description has at least that amount of lines.""" make sure the initial description has at least that amount of lines."""
@ -877,7 +934,7 @@ def show_progress_coinjoin(
indeterminate: bool = False, indeterminate: bool = False,
time_ms: int = 0, time_ms: int = 0,
skip_first_paint: bool = False, skip_first_paint: bool = False,
) -> object: ) -> LayoutObj[UiResult]:
"""Show progress loader for coinjoin. Returns CANCELLED after a specified time when """Show progress loader for coinjoin. Returns CANCELLED after a specified time when
time_ms timeout is passed.""" time_ms timeout is passed."""
@ -890,7 +947,7 @@ def show_homescreen(
notification: str | None, notification: str | None,
notification_level: int = 0, notification_level: int = 0,
skip_first_paint: bool, skip_first_paint: bool,
) -> CANCELLED: ) -> LayoutObj[UiResult]:
"""Idle homescreen.""" """Idle homescreen."""
@ -901,7 +958,7 @@ def show_lockscreen(
bootscreen: bool, bootscreen: bool,
skip_first_paint: bool, skip_first_paint: bool,
coinjoin_authorized: bool = False, coinjoin_authorized: bool = False,
) -> CANCELLED: ) -> LayoutObj[UiResult]:
"""Homescreen for locked device.""" """Homescreen for locked device."""
@ -910,10 +967,10 @@ def confirm_firmware_update(
*, *,
description: str, description: str,
fingerprint: str, fingerprint: str,
) -> None: ) -> LayoutObj[UiResult]:
"""Ask whether to update firmware, optionally show fingerprint. Shared with bootloader.""" """Ask whether to update firmware, optionally show fingerprint. Shared with bootloader."""
# rust/src/ui/model_tt/layout.rs # rust/src/ui/model_tt/layout.rs
def show_wait_text(/, message: str) -> None: def show_wait_text(/, message: str) -> LayoutObj[None]:
"""Show single-line text in the middle of the screen.""" """Show single-line text in the middle of the screen."""