refactor(core): scope payment request text confirmation layouts
What changed, and why it matters
This commit is a small code cleanup in the Trezor hardware wallet's user-interface code. It changes how on-screen payment-request confirmation dialogs are created and destroyed, wrapping them in a 'with' block so they are cleaned up promptly. The developer notes this may be related to an out-of-memory (OOM) issue seen in automated tests, but the commit does not claim to fix a security vulnerability and no independent security references are provided.
Treat as a routine defensive refactor. Review whether the OOM test failure is fully resolved and whether similar un-scoped layout objects exist elsewhere in the UI code. No urgent security response is indicated based on the available materials.
Security signals we found
Potential memory-pressure / OOM hardening in UI flow
Refactor only; no logic or permission changes
No explicit security claim by vendor
No CVE, advisory, or researcher attribution present
Evidence from the diff
The diff modifies four UI layout implementations (bolt, caesar, delizia, eckhart) for confirm_payment_request. Previously, trezorui_api.confirm_value(...) was passed directly as an argument to raise_if_not_confirmed(...), which awaited the result. The refactor stores the layout object in a with ... as obj: context manager and then awaits confirmation on obj. This pattern ensures the layout object is scoped and released deterministically after each iteration, potentially reducing memory pressure when many payment-request text pages are shown. The change is stylistically consistent across all four layout variants and does not alter user-visible behavior or confirmation logic.
Changed components
core/src/trezor/ui/layouts/bolt/__init__.pycore/src/trezor/ui/layouts/caesar/__init__.pycore/src/trezor/ui/layouts/delizia/__init__.pycore/src/trezor/ui/layouts/eckhart/__init__.pyInspect captured patch +27 / −35
diff --git a/core/src/trezor/ui/layouts/bolt/__init__.py b/core/src/trezor/ui/layouts/bolt/__init__.py
index 25b35aaa..dfb688e5 100644
--- a/core/src/trezor/ui/layouts/bolt/__init__.py
+++ b/core/src/trezor/ui/layouts/bolt/__init__.py
@@ -503,15 +503,13 @@ async def confirm_payment_request(
title = TR.words__swap if is_swap(trades) else TR.words__confirm
for t, text in texts:
- await raise_if_not_confirmed(
- trezorui_api.confirm_value(
- title=t or title,
- value=text,
- is_data=False,
- description=None,
- ),
- "confirm_payment_request",
- )
+ with trezorui_api.confirm_value(
+ title=t or title,
+ value=text,
+ is_data=False,
+ description=None,
+ ) as obj:
+ await raise_if_not_confirmed(obj, "confirm_payment_request")
menu_items: list[StrPropertyType] = []
if recipient_address is not None:
diff --git a/core/src/trezor/ui/layouts/caesar/__init__.py b/core/src/trezor/ui/layouts/caesar/__init__.py
index 0c126aa9..801ee911 100644
--- a/core/src/trezor/ui/layouts/caesar/__init__.py
+++ b/core/src/trezor/ui/layouts/caesar/__init__.py
@@ -571,14 +571,12 @@ async def confirm_payment_request(
title = TR.words__swap if is_swap(trades) else TR.words__confirm
for t, text in texts:
- await raise_if_not_confirmed(
- trezorui_api.confirm_value(
- title=t or title,
- value=text,
- description=None,
- ),
- "confirm_payment_request",
- )
+ with trezorui_api.confirm_value(
+ title=t or title,
+ value=text,
+ description=None,
+ ) as obj:
+ await raise_if_not_confirmed(obj, "confirm_payment_request")
menu_items = []
if recipient_address is not None:
diff --git a/core/src/trezor/ui/layouts/delizia/__init__.py b/core/src/trezor/ui/layouts/delizia/__init__.py
index ac9b99c2..04e1432f 100644
--- a/core/src/trezor/ui/layouts/delizia/__init__.py
+++ b/core/src/trezor/ui/layouts/delizia/__init__.py
@@ -509,15 +509,13 @@ async def confirm_payment_request(
title = TR.words__swap if is_swap(trades) else TR.words__confirm
for t, text in texts:
- await raise_if_not_confirmed(
- trezorui_api.confirm_value(
- title=t or title,
- value=text,
- is_data=False,
- description=None,
- ),
- "confirm_payment_request",
- )
+ with trezorui_api.confirm_value(
+ title=t or title,
+ value=text,
+ is_data=False,
+ description=None,
+ ) as obj:
+ await raise_if_not_confirmed(obj, "confirm_payment_request")
main_layout = trezorui_api.confirm_value(
title=title,
diff --git a/core/src/trezor/ui/layouts/eckhart/__init__.py b/core/src/trezor/ui/layouts/eckhart/__init__.py
index 0d00b5d2..cf383f80 100644
--- a/core/src/trezor/ui/layouts/eckhart/__init__.py
+++ b/core/src/trezor/ui/layouts/eckhart/__init__.py
@@ -472,15 +472,13 @@ async def confirm_payment_request(
)
for t, text in texts:
- await raise_if_not_confirmed(
- trezorui_api.confirm_value(
- title=t or title,
- value=text,
- description=None,
- verb=TR.buttons__confirm,
- ),
- "confirm_payment_request",
- )
+ with trezorui_api.confirm_value(
+ title=t or title,
+ value=text,
+ description=None,
+ verb=TR.buttons__confirm,
+ ) as obj:
+ await raise_if_not_confirmed(obj, "confirm_payment_request")
main_layout = trezorui_api.confirm_value(
title=title,
Why this scored 18/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.