refactor(core): enforce layout scoping for `flow_get_address`
What changed, and why it matters
This is a small internal code cleanup in the Trezor firmware's user-interface layer. It changes how the 'show address' screen is wrapped so that the layout object is managed within a scoped context manager rather than passed directly to a helper function. There is no indication this fixes a security bug or changes user-visible behavior.
No security action required. Treat as a normal refactoring commit.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The commit refactors the show_address flows in the Delizia and Eckhart UI layouts to use with trezorui_api.flow_get_address(...) as obj: instead of passing the returned object directly to raise_if_not_confirmed(...). The Rust micropython binding and generated Python stub are updated to reflect that flow_get_address now returns a LayoutContext[UiResult] rather than a LayoutObj[UiResult]. This is a scoping/lifecycle change, not a logic or security fix.
Changed components
core/embed/rust/src/ui/api/firmware_micropython.rscore/mocks/generated/trezorui_api.pyicore/src/trezor/ui/layouts/delizia/__init__.pycore/src/trezor/ui/layouts/eckhart/__init__.pyInspect captured patch +34 / −38
diff --git a/core/embed/rust/src/ui/api/firmware_micropython.rs b/core/embed/rust/src/ui/api/firmware_micropython.rs
index 37d741fe..d6c0a494 100644
--- a/core/embed/rust/src/ui/api/firmware_micropython.rs
+++ b/core/embed/rust/src/ui/api/firmware_micropython.rs
@@ -1763,7 +1763,7 @@ pub static mp_module_trezorui_api: Module = obj_module! {
/// xpubs: Sequence[tuple[str, str]],
/// br_code: ButtonRequestType,
/// br_name: str,
- /// ) -> LayoutObj[UiResult]:
+ /// ) -> LayoutContext[UiResult]:
/// """Get address / receive funds."""
Qstr::MP_QSTR_flow_get_address => obj_fn_kw!(0, new_flow_get_address).as_obj(),
diff --git a/core/mocks/generated/trezorui_api.pyi b/core/mocks/generated/trezorui_api.pyi
index 6d047d20..d573c4dc 100644
--- a/core/mocks/generated/trezorui_api.pyi
+++ b/core/mocks/generated/trezorui_api.pyi
@@ -406,7 +406,7 @@ def flow_get_address(
xpubs: Sequence[tuple[str, str]],
br_code: ButtonRequestType,
br_name: str,
-) -> LayoutObj[UiResult]:
+) -> LayoutContext[UiResult]:
"""Get address / receive funds."""
diff --git a/core/src/trezor/ui/layouts/delizia/__init__.py b/core/src/trezor/ui/layouts/delizia/__init__.py
index 1bc3b989..61a9048e 100644
--- a/core/src/trezor/ui/layouts/delizia/__init__.py
+++ b/core/src/trezor/ui/layouts/delizia/__init__.py
@@ -344,24 +344,22 @@ async def show_address(
)
return result
- await raise_if_not_confirmed(
- trezorui_api.flow_get_address(
- address=address,
- title=title or TR.address__title_receive_address,
- subtitle=None,
- description=network or "",
- hint=None,
- chunkify=chunkify,
- address_qr=address if address_qr is None else address_qr,
- case_sensitive=case_sensitive,
- account=account,
- path=path,
- xpubs=[(xpub_title(i), xpub) for i, xpub in enumerate(xpubs)],
- br_name=br_name,
- br_code=br_code,
- ),
- None,
- )
+ with trezorui_api.flow_get_address(
+ address=address,
+ title=title or TR.address__title_receive_address,
+ subtitle=None,
+ description=network or "",
+ hint=None,
+ chunkify=chunkify,
+ address_qr=address if address_qr is None else address_qr,
+ case_sensitive=case_sensitive,
+ account=account,
+ path=path,
+ xpubs=[(xpub_title(i), xpub) for i, xpub in enumerate(xpubs)],
+ br_name=br_name,
+ br_code=br_code,
+ ) as obj:
+ await raise_if_not_confirmed(obj, br_name=None)
show_continue_in_app(TR.address__confirmed)
diff --git a/core/src/trezor/ui/layouts/eckhart/__init__.py b/core/src/trezor/ui/layouts/eckhart/__init__.py
index d3f66a60..48f76431 100644
--- a/core/src/trezor/ui/layouts/eckhart/__init__.py
+++ b/core/src/trezor/ui/layouts/eckhart/__init__.py
@@ -298,24 +298,22 @@ async def show_address(
if warning is None and multisig_index is not None:
warning = TR.send__receiving_to_multisig
- await raise_if_not_confirmed(
- trezorui_api.flow_get_address(
- address=address,
- title=title or TR.words__receive,
- subtitle=subtitle,
- description=network or "",
- hint=warning,
- chunkify=chunkify,
- address_qr=address if address_qr is None else address_qr,
- case_sensitive=case_sensitive,
- account=account,
- path=path,
- xpubs=[(xpub_title(i), xpub) for i, xpub in enumerate(xpubs)],
- br_name=br_name,
- br_code=br_code,
- ),
- None,
- )
+ with trezorui_api.flow_get_address(
+ address=address,
+ title=title or TR.words__receive,
+ subtitle=subtitle,
+ description=network or "",
+ hint=warning,
+ chunkify=chunkify,
+ address_qr=address if address_qr is None else address_qr,
+ case_sensitive=case_sensitive,
+ account=account,
+ path=path,
+ xpubs=[(xpub_title(i), xpub) for i, xpub in enumerate(xpubs)],
+ br_name=br_name,
+ br_code=br_code,
+ ) as obj:
+ await raise_if_not_confirmed(obj, br_name=None)
show_continue_in_app(TR.address__confirmed)
Why this scored 11/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.