chore: include confirm_trade in BTC only
What changed, and why it matters
This commit moves the same on-screen trade-confirmation helper from the non-Bitcoin code block into the common, always-compiled section across four Trezor device layouts. The function itself is not changed; it is only made available in the Bitcoin-only firmware build as well as the full build. There is no direct evidence in the commit that this fixes a security bug.
No immediate action required. Treat as routine refactor. If this is part of a larger feature, review the callers of `confirm_trade` in Bitcoin-only flows to ensure the trade details shown to the user are complete and accurate before signing.
Security signals we found
No security-relevant code change: function body is byte-for-byte identical
Scope expansion: helper now compiled into Bitcoin-only firmware
No changelog entry and title marked as chore, indicating routine maintenance
Evidence from the diff
The change relocates confirm_trade in bolt, caesar, delizia, and eckhart UI layout modules from inside the if not utils.BITCOIN_ONLY: guard to the top-level module scope. The implementation is identical before and after, so this is a build-availability refactor. It likely supports a new Bitcoin-only trade/signing flow (e.g., DEX swaps or coinjoin-like operations) that previously could not call this layout in BITCOIN_ONLY builds. No input validation, privilege, or logic changes are visible in the diff.
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 +138 / −134
diff --git a/core/src/trezor/ui/layouts/bolt/__init__.py b/core/src/trezor/ui/layouts/bolt/__init__.py
index 0bea9c8c..720f8660 100644
--- a/core/src/trezor/ui/layouts/bolt/__init__.py
+++ b/core/src/trezor/ui/layouts/bolt/__init__.py
@@ -980,6 +980,43 @@ def _confirm_summary(
return with_info(total_layout, info_layout, br_name, br_code)
+async def confirm_trade(
+ title: str,
+ sell_amount: str | None,
+ buy_amount: str,
+ address: str,
+ account: str | None,
+ account_path: str | None,
+ extra_menu_items: list[tuple[str, str]],
+) -> None:
+ menu_items: list[PropertyType] = [
+ (TR.address__title_receive_address, address, None)
+ ]
+ if account:
+ menu_items.append((TR.words__account, account, None))
+ if account_path:
+ menu_items.append((TR.address_details__derivation_path, account_path, None))
+ for k, v in extra_menu_items:
+ menu_items.append((k, v, None))
+
+ items = []
+ if sell_amount is not None:
+ items.append(("", sell_amount, None))
+ items.append(("", buy_amount, None))
+ await with_info(
+ trezorui_api.confirm_properties(
+ title=title,
+ items=items,
+ external_menu=True,
+ ),
+ trezorui_api.confirm_properties(
+ title="", items=menu_items, verb=TR.buttons__close
+ ),
+ "confirm_trade",
+ ButtonRequestType.SignTx,
+ )
+
+
if not utils.BITCOIN_ONLY:
def confirm_ethereum_unknown_contract_warning(
@@ -1170,42 +1207,6 @@ if not utils.BITCOIN_ONLY:
TR.confirm_total__title_fee,
)
- async def confirm_trade(
- title: str,
- sell_amount: str | None,
- buy_amount: str,
- address: str,
- account: str | None,
- account_path: str | None,
- extra_menu_items: list[tuple[str, str]],
- ) -> None:
- menu_items: list[PropertyType] = [
- (TR.address__title_receive_address, address, None)
- ]
- if account:
- menu_items.append((TR.words__account, account, None))
- if account_path:
- menu_items.append((TR.address_details__derivation_path, account_path, None))
- for k, v in extra_menu_items:
- menu_items.append((k, v, None))
-
- items = []
- if sell_amount is not None:
- items.append(("", sell_amount, None))
- items.append(("", buy_amount, None))
- await with_info(
- trezorui_api.confirm_properties(
- title=title,
- items=items,
- external_menu=True,
- ),
- trezorui_api.confirm_properties(
- title="", items=menu_items, verb=TR.buttons__close
- ),
- "confirm_trade",
- ButtonRequestType.SignTx,
- )
-
async def confirm_ethereum_staking_tx(
title: str,
intro_question: str,
diff --git a/core/src/trezor/ui/layouts/caesar/__init__.py b/core/src/trezor/ui/layouts/caesar/__init__.py
index cee91760..9fb04008 100644
--- a/core/src/trezor/ui/layouts/caesar/__init__.py
+++ b/core/src/trezor/ui/layouts/caesar/__init__.py
@@ -1032,6 +1032,41 @@ def confirm_total(
)
+async def confirm_trade(
+ title: str,
+ sell_amount: str | None,
+ buy_amount: str,
+ address: str,
+ account: str | None,
+ account_path: str | None,
+ extra_menu_items: list[tuple[str, str]],
+) -> None:
+ from trezor.ui.layouts.menu import Menu, confirm_with_menu
+
+ items = []
+ if sell_amount is not None:
+ items.append(("", sell_amount, True))
+ items.append(("", buy_amount, True))
+ trade_layout = trezorui_api.confirm_properties(
+ title=title,
+ items=items,
+ verb=TR.buttons__continue,
+ external_menu=True,
+ )
+
+ account_items: list[PropertyType] = [("", address, None)]
+ if account:
+ account_items.append((TR.words__account, account, None))
+ if account_path:
+ 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))
+ menu = Menu.root(menu_items)
+
+ await confirm_with_menu(trade_layout, menu, "confirm_trade")
+
+
if not utils.BITCOIN_ONLY:
def confirm_ethereum_unknown_contract_warning(
@@ -1162,40 +1197,6 @@ if not utils.BITCOIN_ONLY:
br_name="confirm_ethereum_approve",
)
- async def confirm_trade(
- title: str,
- sell_amount: str | None,
- buy_amount: str,
- address: str,
- account: str | None,
- account_path: str | None,
- extra_menu_items: list[tuple[str, str]],
- ) -> None:
- from trezor.ui.layouts.menu import Menu, confirm_with_menu
-
- items = []
- if sell_amount is not None:
- items.append(("", sell_amount, True))
- items.append(("", buy_amount, True))
- trade_layout = trezorui_api.confirm_properties(
- title=title,
- items=items,
- verb=TR.buttons__continue,
- external_menu=True,
- )
-
- account_items: list[PropertyType] = [("", address, None)]
- if account:
- account_items.append((TR.words__account, account, None))
- if account_path:
- 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))
- menu = Menu.root(menu_items)
-
- await confirm_with_menu(trade_layout, menu, "confirm_trade")
-
async def confirm_ethereum_staking_tx(
title: str,
intro_question: str,
diff --git a/core/src/trezor/ui/layouts/delizia/__init__.py b/core/src/trezor/ui/layouts/delizia/__init__.py
index 2eebcad2..34e7ef5f 100644
--- a/core/src/trezor/ui/layouts/delizia/__init__.py
+++ b/core/src/trezor/ui/layouts/delizia/__init__.py
@@ -925,6 +925,38 @@ def _confirm_summary(
)
+async def confirm_trade(
+ title: str,
+ subtitle: str,
+ sell_amount: str | None,
+ buy_amount: str,
+ address: str,
+ account: str | None,
+ account_path: str | None,
+ extra_menu_items: list[tuple[str, str]],
+) -> None:
+ from trezor.ui.layouts.menu import Menu, confirm_with_menu
+
+ trade_layout = trezorui_api.confirm_trade(
+ title=title,
+ subtitle=subtitle,
+ sell_amount=sell_amount,
+ buy_amount=buy_amount,
+ )
+
+ account_items: list[PropertyType] = [("", address, None)]
+ if account:
+ account_items.append((TR.words__account, account, None))
+ if account_path:
+ 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))
+ menu = Menu.root(menu_items, TR.send__cancel_sign)
+
+ await confirm_with_menu(trade_layout, menu, "confirm_trade")
+
+
if not utils.BITCOIN_ONLY:
def confirm_ethereum_unknown_contract_warning(
@@ -1116,37 +1148,6 @@ if not utils.BITCOIN_ONLY:
TR.confirm_total__title_fee,
)
- async def confirm_trade(
- title: str,
- subtitle: str,
- sell_amount: str | None,
- buy_amount: str,
- address: str,
- account: str | None,
- account_path: str | None,
- extra_menu_items: list[tuple[str, str]],
- ) -> None:
- from trezor.ui.layouts.menu import Menu, confirm_with_menu
-
- trade_layout = trezorui_api.confirm_trade(
- title=title,
- subtitle=subtitle,
- sell_amount=sell_amount,
- buy_amount=buy_amount,
- )
-
- account_items: list[PropertyType] = [("", address, None)]
- if account:
- account_items.append((TR.words__account, account, None))
- if account_path:
- 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))
- menu = Menu.root(menu_items, TR.send__cancel_sign)
-
- await confirm_with_menu(trade_layout, menu, "confirm_trade")
-
async def confirm_ethereum_staking_tx(
title: str,
intro_question: str,
diff --git a/core/src/trezor/ui/layouts/eckhart/__init__.py b/core/src/trezor/ui/layouts/eckhart/__init__.py
index e1c76961..f174cfc7 100644
--- a/core/src/trezor/ui/layouts/eckhart/__init__.py
+++ b/core/src/trezor/ui/layouts/eckhart/__init__.py
@@ -928,6 +928,40 @@ def _confirm_summary(
)
+def confirm_trade(
+ title: str,
+ subtitle: str,
+ sell_amount: str | None,
+ buy_amount: str,
+ address: str,
+ account: str | None,
+ account_path: str | None,
+ extra_menu_items: list[tuple[str, str]],
+ back_button: bool,
+) -> Awaitable[ui.UiResult]:
+ from trezor.ui.layouts.menu import Menu, interact_with_menu
+
+ trade_layout = trezorui_api.confirm_trade(
+ title=title,
+ subtitle=subtitle,
+ sell_amount=sell_amount,
+ buy_amount=buy_amount,
+ back_button=back_button,
+ )
+
+ account_info: list[PropertyType] = [("", address, True)]
+ if account:
+ account_info.append((TR.words__account, account, True))
+ if account_path:
+ 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))
+ menu = Menu.root(menu_items, TR.send__cancel_sign)
+
+ return interact_with_menu(trade_layout, menu, "confirm_trade")
+
+
if not utils.BITCOIN_ONLY:
def confirm_ethereum_unknown_contract_warning(title: str | None) -> Awaitable[None]:
@@ -1144,39 +1178,6 @@ if not utils.BITCOIN_ONLY:
TR.confirm_total__title_fee,
)
- def confirm_trade(
- title: str,
- subtitle: str,
- sell_amount: str | None,
- buy_amount: str,
- address: str,
- account: str | None,
- account_path: str | None,
- extra_menu_items: list[tuple[str, str]],
- back_button: bool,
- ) -> Awaitable[ui.UiResult]:
- from trezor.ui.layouts.menu import Menu, interact_with_menu
-
- trade_layout = trezorui_api.confirm_trade(
- title=title,
- subtitle=subtitle,
- sell_amount=sell_amount,
- buy_amount=buy_amount,
- back_button=back_button,
- )
-
- account_info: list[PropertyType] = [("", address, True)]
- if account:
- account_info.append((TR.words__account, account, True))
- if account_path:
- 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))
- menu = Menu.root(menu_items, TR.send__cancel_sign)
-
- return interact_with_menu(trade_layout, menu, "confirm_trade")
-
async def confirm_ethereum_staking_tx(
title: str,
intro_question: str,
Why this scored 17/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.