refactor: payment requests with no recipient address
What changed, and why it matters
This commit refactors how Trezor hardware wallets display payment requests when no recipient address is provided. Previously, the code always expected a recipient address and would include it in the confirmation screen. Now, it handles cases where the recipient address is missing by either omitting that detail or showing a simpler confirmation. There is no direct evidence this fixes an active security vulnerability; it appears to be a UI robustness improvement.
No immediate security action required. Treat as a normal UI refactor. If this change relates to a new feature allowing payment requests without recipient addresses, ensure the upstream callers validate that missing addresses are intentional and not the result of malformed or truncated messages.
Security signals we found
Parameter type changed from required string to optional string (str | None)
Conditional rendering added to avoid displaying a missing recipient address
No changelog entry; labeled as refactor
No explicit security keywords in commit title or message
Evidence from the diff
The commit changes the confirm_payment_request function signature across four UI layout implementations (bolt, caesar, delizia, eckhart) so that recipient becomes recipient_address: str | None. It adds conditional logic to only include the provider address in the confirmation menu when present. In the caesar layout, when no menu items exist, it falls back to a simpler confirm_properties flow. Minor formatting changes to unrelated derivation-path lines are also present. No changelog entry is included, and the commit is titled as a refactor.
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 +42 / −29
diff --git a/core/src/trezor/ui/layouts/bolt/__init__.py b/core/src/trezor/ui/layouts/bolt/__init__.py
index 38aba1ba..0bea9c8c 100644
--- a/core/src/trezor/ui/layouts/bolt/__init__.py
+++ b/core/src/trezor/ui/layouts/bolt/__init__.py
@@ -487,7 +487,7 @@ def show_continue_in_app(content: str) -> None:
async def confirm_payment_request(
recipient_name: str,
- recipient: str,
+ recipient_address: str | None,
texts: Iterable[tuple[str | None, str]],
refunds: Iterable[tuple[str, str | None, str | None]],
trades: list[tuple[str | None, str, str, str | None, str | None]],
@@ -511,9 +511,9 @@ async def confirm_payment_request(
"confirm_payment_request",
)
- menu_items: list[PropertyType] = [
- (TR.address__title_provider_address, recipient, None)
- ]
+ menu_items: list[PropertyType] = []
+ if recipient_address is not None:
+ menu_items.append((TR.address__title_provider_address, recipient_address, None))
for r_address, r_account, r_account_path in refunds:
menu_items.append((TR.address__title_refund_address, r_address, None))
if r_account:
diff --git a/core/src/trezor/ui/layouts/caesar/__init__.py b/core/src/trezor/ui/layouts/caesar/__init__.py
index 53e26fcb..cee91760 100644
--- a/core/src/trezor/ui/layouts/caesar/__init__.py
+++ b/core/src/trezor/ui/layouts/caesar/__init__.py
@@ -552,7 +552,7 @@ def show_continue_in_app(content: str) -> None:
async def confirm_payment_request(
recipient_name: str,
- recipient: str,
+ recipient_address: str | None,
texts: Iterable[tuple[str | None, str]],
refunds: Iterable[tuple[str, str | None, str | None]],
trades: list[tuple[str | None, str, str, str | None, str | None]],
@@ -577,15 +577,11 @@ async def confirm_payment_request(
"confirm_payment_request",
)
- main_layout = trezorui_api.confirm_with_info(
- title=(TR.words__swap if is_swap else TR.words__confirm),
- items=[(TR.words__provider, True), (recipient_name, False)],
- verb=TR.buttons__continue,
- verb_info=TR.buttons__info,
- external_menu=True,
- )
-
- menu_items = [create_details(TR.address__title_provider_address, recipient)]
+ menu_items = []
+ if recipient_address is not None:
+ menu_items.append(
+ create_details(TR.address__title_provider_address, recipient_address)
+ )
for r_address, r_account, r_account_path in refunds:
refund_account_items: list[PropertyType] = [("", r_address, None)]
if r_account:
@@ -600,9 +596,24 @@ async def confirm_payment_request(
refund_account_items,
)
)
- menu = Menu.root(menu_items)
+ if menu_items:
+ menu = Menu.root(menu_items)
- await confirm_with_menu(main_layout, menu, "confirm_payment_request")
+ main_layout = trezorui_api.confirm_with_info(
+ title=(TR.words__swap if is_swap else TR.words__confirm),
+ items=[(TR.words__provider, True), (recipient_name, False)],
+ verb=TR.buttons__continue,
+ verb_info=TR.buttons__info,
+ external_menu=True,
+ )
+
+ await confirm_with_menu(main_layout, menu, "confirm_payment_request")
+ else:
+ await confirm_properties(
+ "confirm_payment_request",
+ (TR.words__swap if is_swap else TR.words__confirm),
+ [(TR.words__provider, recipient_name, True)],
+ )
for sell_amount, buy_amount, t_address, t_account, t_account_path in trades:
await confirm_trade(
@@ -1177,9 +1188,7 @@ if not utils.BITCOIN_ONLY:
if account:
account_items.append((TR.words__account, account, None))
if account_path:
- account_items.append(
- (TR.address_details__derivation_path, account_path, None)
- )
+ account_items.append((TR.address_details__derivation_path, account_path, None))
menu_items = [create_details(TR.address__title_receive_address, account_items)]
for k, v in extra_menu_items:
menu_items.append(create_details(k, v))
diff --git a/core/src/trezor/ui/layouts/delizia/__init__.py b/core/src/trezor/ui/layouts/delizia/__init__.py
index 56e4f076..2eebcad2 100644
--- a/core/src/trezor/ui/layouts/delizia/__init__.py
+++ b/core/src/trezor/ui/layouts/delizia/__init__.py
@@ -485,7 +485,7 @@ def show_continue_in_app(content: str) -> None:
async def confirm_payment_request(
recipient_name: str,
- recipient: str,
+ recipient_address: str | None,
texts: Iterable[tuple[str | None, str]],
refunds: Iterable[tuple[str, str | None, str | None]],
trades: list[tuple[str | None, str, str, str | None, str | None]],
@@ -522,7 +522,11 @@ async def confirm_payment_request(
external_menu=True,
)
- menu_items = [create_details(TR.address__title_provider_address, recipient)]
+ menu_items = []
+ if recipient_address is not None:
+ menu_items.append(
+ create_details(TR.address__title_provider_address, recipient_address)
+ )
for r_address, r_account, r_account_path in refunds:
refund_account_items: list[PropertyType] = [("", r_address, None)]
if r_account:
@@ -1135,9 +1139,7 @@ if not utils.BITCOIN_ONLY:
if account:
account_items.append((TR.words__account, account, None))
if account_path:
- account_items.append(
- (TR.address_details__derivation_path, account_path, None)
- )
+ account_items.append((TR.address_details__derivation_path, account_path, None))
menu_items = [create_details(TR.address__title_receive_address, account_items)]
for k, v in extra_menu_items:
menu_items.append(create_details(k, v))
diff --git a/core/src/trezor/ui/layouts/eckhart/__init__.py b/core/src/trezor/ui/layouts/eckhart/__init__.py
index 0fcb5e86..e1c76961 100644
--- a/core/src/trezor/ui/layouts/eckhart/__init__.py
+++ b/core/src/trezor/ui/layouts/eckhart/__init__.py
@@ -446,7 +446,7 @@ def show_continue_in_app(content: str) -> None:
async def confirm_payment_request(
recipient_name: str,
- recipient: str,
+ recipient_address: str | None,
texts: Iterable[tuple[str | None, str]],
refunds: Iterable[tuple[str, str | None, str | None]],
trades: list[tuple[str | None, str, str, str | None, str | None]],
@@ -483,7 +483,11 @@ async def confirm_payment_request(
external_menu=True,
)
- menu_items = [create_details(TR.address__title_provider_address, recipient)]
+ menu_items = []
+ if recipient_address is not None:
+ menu_items.append(
+ create_details(TR.address__title_provider_address, recipient_address)
+ )
for r_address, r_account, r_account_path in refunds:
refund_account_info: list[PropertyType] = [(str(""), r_address, True)]
if r_account:
@@ -1165,9 +1169,7 @@ if not utils.BITCOIN_ONLY:
if account:
account_info.append((TR.words__account, account, True))
if account_path:
- account_info.append(
- (TR.address_details__derivation_path, account_path, True)
- )
+ account_info.append((TR.address_details__derivation_path, account_path, True))
menu_items = [create_details(TR.address__title_receive_address, account_info)]
for k, v in extra_menu_items:
menu_items.append(create_details(k, v))
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.