fix(core): remove double _colon strings from show_address_details
What changed, and why it matters
This commit is a straightforward user-interface string refactor. It moves the colon that appears after labels like 'Account:' and 'Derivation path:' out of the embedded Rust translation strings and into the Python code that calls the address-details screen. There is no security-relevant change in behavior—only where the colon is appended.
No security action required. Treat as a normal UI refactor during review/QA.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The patch refactors show_address_details across Trezor firmware UI layouts. Previously, Rust code used hard-coded translated strings ending in a colon (e.g., TR::words__account_colon, TR::address_details__derivation_path_colon). The change introduces account_label and path_label parameters so the caller supplies the already-colon-suffixed label, typically via with_colon(TR.words__account) and with_colon(TR.address_details__derivation_path). The Rust code no longer references the _colon translation keys directly. This is a code-quality/localization refactor with no functional or security impact.
Changed components
core/embed/rust/src/ui/layout_bolt/component/address_details.rscore/embed/rust/src/ui/layout_bolt/ui_firmware.rscore/embed/rust/src/ui/layout_caesar/component/address_details.rscore/embed/rust/src/ui/layout_caesar/ui_firmware.rscore/embed/rust/src/ui/layout_delizia/ui_firmware.rscore/embed/rust/src/ui/layout_eckhart/ui_firmware.rscore/embed/rust/src/ui/ui_firmware.rscore/embed/rust/src/ui/api/firmware_micropython.rscore/src/trezor/ui/layouts/bolt/__init__.pycore/src/trezor/ui/layouts/caesar/__init__.pycore/src/trezor/wire/thp/ui.pyInspect captured patch +48 / −19
### core/embed/rust/librust_qstr.h
@@ -99,6 +99,7 @@ static void _librust_qstrs(void) {
MP_QSTR_about_items;
MP_QSTR_account;
MP_QSTR_account_items;
+ MP_QSTR_account_label;
MP_QSTR_account_title;
MP_QSTR_accounts;
MP_QSTR_action;
@@ -565,6 +566,7 @@ static void _librust_qstrs(void) {
MP_QSTR_passphrase__turn_on;
MP_QSTR_passphrase__wallet;
MP_QSTR_path;
+ MP_QSTR_path_label;
MP_QSTR_peer_count;
MP_QSTR_pin__cancel_description;
MP_QSTR_pin__cancel_info;
### core/embed/rust/src/ui/api/firmware_micropython.rs
@@ -793,7 +793,9 @@ extern "C" fn new_show_address_details(n_args: usize, args: *const Obj, kwargs:
let details_title: TString = kwargs.get(Qstr::MP_QSTR_details_title)?.try_into()?;
let address: TString = kwargs.get(Qstr::MP_QSTR_address)?.try_into()?;
let case_sensitive: bool = kwargs.get(Qstr::MP_QSTR_case_sensitive)?.try_into()?;
+ let account_label: TString = kwargs.get(Qstr::MP_QSTR_account_label)?.try_into()?;
let account: Option<TString> = kwargs.get(Qstr::MP_QSTR_account)?.try_into_option()?;
+ let path_label: TString = kwargs.get(Qstr::MP_QSTR_path_label)?.try_into()?;
let path: Option<TString> = kwargs.get(Qstr::MP_QSTR_path)?.try_into_option()?;
let xpubs: Obj = kwargs.get(Qstr::MP_QSTR_xpubs)?;
@@ -802,7 +804,9 @@ extern "C" fn new_show_address_details(n_args: usize, args: *const Obj, kwargs:
address,
case_sensitive,
details_title,
+ account_label,
account,
+ path_label,
path,
xpubs,
)?;
@@ -1850,7 +1854,9 @@ pub static mp_module_trezorui_api: Module = obj_module! {
/// address: str,
/// case_sensitive: bool,
/// details_title: str,
+ /// account_label: str,
/// account: str | None,
+ /// path_label: str,
/// path: str | None,
/// xpubs: Sequence[tuple[str, str]],
/// ) -> LayoutContext[UiResult]:
### core/embed/rust/src/ui/layout_bolt/component/address_details.rs
@@ -4,7 +4,6 @@ use super::{theme, Frame, FrameMsg};
use crate::micropython::buffer::StrBuffer;
use crate::micropython::Error;
use crate::strutil::TString;
-use crate::translations::TR;
use crate::ui::component::text::paragraphs::{
Paragraph, ParagraphSource, ParagraphVecShort, Paragraphs, VecExt,
};
@@ -29,23 +28,19 @@ impl AddressDetails {
qr_address: TString<'static>,
case_sensitive: bool,
details_title: TString<'static>,
+ account_label: TString<'static>,
account: Option<TString<'static>>,
+ path_label: TString<'static>,
path: Option<TString<'static>>,
) -> Result<Self, Error> {
let mut para = ParagraphVecShort::new();
- if let Some(a) = account {
- para.add(Paragraph::new(
- &theme::TEXT_NORMAL,
- TR::words__account_colon,
- ));
- para.add(Paragraph::new(&theme::TEXT_MONO_DATA, a));
+ if let Some(account) = account {
+ para.add(Paragraph::new(&theme::TEXT_NORMAL, account_label));
+ para.add(Paragraph::new(&theme::TEXT_MONO_DATA, account));
}
- if let Some(p) = path {
- para.add(Paragraph::new(
- &theme::TEXT_NORMAL,
- TR::address_details__derivation_path_colon,
- ));
- para.add(Paragraph::new(&theme::TEXT_MONO_DATA, p));
+ if let Some(path) = path {
+ para.add(Paragraph::new(&theme::TEXT_NORMAL, path_label));
+ para.add(Paragraph::new(&theme::TEXT_MONO_DATA, path));
}
let result = Self {
qr_code: Frame::left_aligned(
### core/embed/rust/src/ui/layout_bolt/ui_firmware.rs
@@ -790,7 +790,9 @@ impl FirmwareUI for UIBolt {
address: TString<'static>,
case_sensitive: bool,
details_title: TString<'static>,
+ account_label: TString<'static>,
account: Option<TString<'static>>,
+ path_label: TString<'static>,
path: Option<TString<'static>>,
xpubs: Obj,
) -> Result<impl LayoutMaybeTrace, Error> {
@@ -799,7 +801,9 @@ impl FirmwareUI for UIBolt {
address,
case_sensitive,
details_title,
+ account_label,
account,
+ path_label,
path,
)?;
### core/embed/rust/src/ui/layout_caesar/component/address_details.rs
@@ -33,7 +33,9 @@ impl AddressDetails {
pub fn new(
qr_address: TString<'static>,
case_sensitive: bool,
+ account_label: TString<'static>,
account: Option<TString<'static>>,
+ path_label: TString<'static>,
path: Option<TString<'static>>,
) -> Result<Self, Error> {
let qr_code = qr_address
@@ -42,14 +44,11 @@ impl AddressDetails {
let details_view = {
let mut para = ParagraphVecShort::new();
if let Some(account) = account {
- para.add(Paragraph::new(&theme::TEXT_BOLD, TR::words__account_colon));
+ para.add(Paragraph::new(&theme::TEXT_BOLD, account_label));
para.add(Paragraph::new(&theme::TEXT_MONO, account));
}
if let Some(path) = path {
- para.add(Paragraph::new(
- &theme::TEXT_BOLD,
- TR::address_details__derivation_path_colon,
- ));
+ para.add(Paragraph::new(&theme::TEXT_BOLD, path_label));
para.add(Paragraph::new(&theme::TEXT_MONO, path));
}
Paragraphs::new(para)
### core/embed/rust/src/ui/layout_caesar/ui_firmware.rs
@@ -983,11 +983,20 @@ impl FirmwareUI for UICaesar {
address: TString<'static>,
case_sensitive: bool,
_details_title: TString<'static>,
+ account_label: TString<'static>,
account: Option<TString<'static>>,
+ path_label: TString<'static>,
path: Option<TString<'static>>,
xpubs: Obj,
) -> Result<impl LayoutMaybeTrace, Error> {
- let mut ad = AddressDetails::new(address, case_sensitive, account, path)?;
+ let mut ad = AddressDetails::new(
+ address,
+ case_sensitive,
+ account_label,
+ account,
+ path_label,
+ path,
+ )?;
for i in IterBuf::new().try_iterate(xpubs)? {
let [xtitle, text]: [StrBuffer; 2] = util::iter_into_array(i)?;
### core/embed/rust/src/ui/layout_delizia/ui_firmware.rs
@@ -789,7 +789,9 @@ impl FirmwareUI for UIDelizia {
_address: TString<'static>,
_case_sensitive: bool,
_details_title: TString<'static>,
+ _account_label: TString<'static>,
_account: Option<TString<'static>>,
+ _path_label: TString<'static>,
_path: Option<TString<'static>>,
_xpubs: Obj,
) -> Result<impl LayoutMaybeTrace, Error> {
### core/embed/rust/src/ui/layout_eckhart/ui_firmware.rs
@@ -957,7 +957,9 @@ impl FirmwareUI for UIEckhart {
_address: TString<'static>,
_case_sensitive: bool,
_details_title: TString<'static>,
+ _account_label: TString<'static>,
_account: Option<TString<'static>>,
+ _path_label: TString<'static>,
_path: Option<TString<'static>>,
_xpubs: Obj,
) -> Result<impl LayoutMaybeTrace, Error> {
### core/embed/rust/src/ui/ui_firmware.rs
@@ -409,7 +409,9 @@ pub trait FirmwareUI {
address: TString<'static>,
case_sensitive: bool,
details_title: TString<'static>,
+ account_label: TString<'static>,
account: Option<TString<'static>>,
+ path_label: TString<'static>,
path: Option<TString<'static>>,
xpubs: Obj, // TODO: replace Obj
) -> Result<impl LayoutMaybeTrace, Error>;
### core/mocks/generated/trezorui_api.pyi
@@ -580,7 +580,9 @@ def show_address_details(
address: str,
case_sensitive: bool,
details_title: str,
+ account_label: str,
account: str | None,
+ path_label: str,
path: str | None,
xpubs: Sequence[tuple[str, str]],
) -> LayoutContext[UiResult]:
### core/src/trezor/ui/layouts/bolt/__init__.py
@@ -368,7 +368,9 @@ def xpub_title(i: int) -> str:
address=address if address_qr is None else address_qr,
case_sensitive=case_sensitive,
details_title=details_title,
+ account_label=with_colon(TR.words__account),
account=account,
+ path_label=with_colon(TR.address_details__derivation_path),
path=path,
xpubs=[(xpub_title(i), xpub) for i, xpub in enumerate(xpubs)],
) as layout:
### core/src/trezor/ui/layouts/caesar/__init__.py
@@ -376,7 +376,9 @@ def xpub_title(i: int) -> str:
address=address if address_qr is None else address_qr,
case_sensitive=case_sensitive,
details_title="", # unused on this model
+ account_label=with_colon(TR.words__account),
account=account,
+ path_label=with_colon(TR.address_details__derivation_path),
path=path,
xpubs=[(xpub_title(i), xpub) for i, xpub in enumerate(xpubs)],
) as layout:
### core/src/trezor/wire/thp/ui.py
@@ -110,7 +110,9 @@ async def show_qr_code_screen(qr_code_str: str) -> UiResult:
address=qr_code_str,
case_sensitive=True,
details_title="",
+ account_label="",
account="",
+ path_label="",
path="",
xpubs=[],
) as layout:Why this scored 15/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.