fix(core): combine path/account with labels
What changed, and why it matters
This commit is a straightforward user-interface refactoring. It bundles an account/path label together with its corresponding value into a single tuple, instead of passing them as four separate arguments. There is no security-relevant change visible in the code.
No security action needed. This is a benign UI refactor.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The patch refactors the show_address_details API across multiple Trezor UI layouts. It removes separate account_label/path_label parameters and changes account/path from Option<TString> to Option<(TString, TString)> (label + content). All call sites are updated to construct these tuples. No logic affecting authorization, cryptography, memory safety, or trust assumptions is modified.
Changed components
core/embed/rust/src/ui/api/firmware_micropython.rscore/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/mocks/generated/trezorui_api.pyicore/src/trezor/ui/layouts/bolt/__init__.pycore/src/trezor/ui/layouts/caesar/__init__.pycore/src/trezor/wire/thp/ui.pyInspect captured patch +51 / −74
### core/embed/rust/librust_qstr.h
@@ -99,7 +99,6 @@ 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,7 +564,6 @@ 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,20 +793,24 @@ 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 labeled = |obj: Obj| -> Result<Option<(TString, TString)>, Error> {
+ if obj == Obj::const_none() {
+ Ok(None)
+ } else {
+ let [label, content]: [Obj; 2] = util::iter_into_array(obj)?;
+ Ok(Some((label.try_into()?, content.try_into()?)))
+ }
+ };
+ let account = labeled(kwargs.get(Qstr::MP_QSTR_account)?)?;
+ let path = labeled(kwargs.get(Qstr::MP_QSTR_path)?)?;
let xpubs: Obj = kwargs.get(Qstr::MP_QSTR_xpubs)?;
let layout = ModelUI::show_address_details(
qr_title,
address,
case_sensitive,
details_title,
- account_label,
account,
- path_label,
path,
xpubs,
)?;
@@ -1854,10 +1858,8 @@ 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,
+ /// account: tuple[str, str] | None,
+ /// path: tuple[str, str] | None,
/// xpubs: Sequence[tuple[str, str]],
/// ) -> LayoutContext[UiResult]:
/// """Show address details - QR code, account, path, cosigner xpubs."""
### core/embed/rust/src/ui/layout_bolt/component/address_details.rs
@@ -28,18 +28,16 @@ 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>>,
+ account: Option<(TString<'static>, TString<'static>)>,
+ path: Option<(TString<'static>, TString<'static>)>,
) -> Result<Self, Error> {
let mut para = ParagraphVecShort::new();
- if let Some(account) = account {
- para.add(Paragraph::new(&theme::TEXT_NORMAL, account_label));
+ if let Some((label, account)) = account {
+ para.add(Paragraph::new(&theme::TEXT_NORMAL, label));
para.add(Paragraph::new(&theme::TEXT_MONO_DATA, account));
}
- if let Some(path) = path {
- para.add(Paragraph::new(&theme::TEXT_NORMAL, path_label));
+ if let Some((label, path)) = path {
+ para.add(Paragraph::new(&theme::TEXT_NORMAL, label));
para.add(Paragraph::new(&theme::TEXT_MONO_DATA, path));
}
let result = Self {
### core/embed/rust/src/ui/layout_bolt/ui_firmware.rs
@@ -790,20 +790,16 @@ 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>>,
+ account: Option<(TString<'static>, TString<'static>)>,
+ path: Option<(TString<'static>, TString<'static>)>,
xpubs: Obj,
) -> Result<impl LayoutMaybeTrace, Error> {
let mut ad = AddressDetails::new(
qr_title,
address,
case_sensitive,
details_title,
- account_label,
account,
- path_label,
path,
)?;
### core/embed/rust/src/ui/layout_caesar/component/address_details.rs
@@ -33,22 +33,20 @@ 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>>,
+ account: Option<(TString<'static>, TString<'static>)>,
+ path: Option<(TString<'static>, TString<'static>)>,
) -> Result<Self, Error> {
let qr_code = qr_address
.map(|s| Qr::new(s, case_sensitive))?
.with_border(QR_BORDER);
let details_view = {
let mut para = ParagraphVecShort::new();
- if let Some(account) = account {
- para.add(Paragraph::new(&theme::TEXT_BOLD, account_label));
+ if let Some((label, account)) = account {
+ para.add(Paragraph::new(&theme::TEXT_BOLD, label));
para.add(Paragraph::new(&theme::TEXT_MONO, account));
}
- if let Some(path) = path {
- para.add(Paragraph::new(&theme::TEXT_BOLD, path_label));
+ if let Some((label, path)) = path {
+ para.add(Paragraph::new(&theme::TEXT_BOLD, label));
para.add(Paragraph::new(&theme::TEXT_MONO, path));
}
Paragraphs::new(para)
### core/embed/rust/src/ui/layout_caesar/ui_firmware.rs
@@ -983,20 +983,11 @@ 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>>,
+ account: Option<(TString<'static>, TString<'static>)>,
+ path: Option<(TString<'static>, TString<'static>)>,
xpubs: Obj,
) -> Result<impl LayoutMaybeTrace, Error> {
- let mut ad = AddressDetails::new(
- address,
- case_sensitive,
- account_label,
- account,
- path_label,
- path,
- )?;
+ let mut ad = AddressDetails::new(address, case_sensitive, account, 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,10 +789,8 @@ 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>>,
+ _account: Option<(TString<'static>, TString<'static>)>,
+ _path: Option<(TString<'static>, TString<'static>)>,
_xpubs: Obj,
) -> Result<impl LayoutMaybeTrace, Error> {
Err::<RootComponent<Empty, ModelUI>, Error>(Error::NotImplementedError)
### core/embed/rust/src/ui/layout_eckhart/ui_firmware.rs
@@ -957,10 +957,8 @@ 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>>,
+ _account: Option<(TString<'static>, TString<'static>)>,
+ _path: Option<(TString<'static>, TString<'static>)>,
_xpubs: Obj,
) -> Result<impl LayoutMaybeTrace, Error> {
Err::<RootComponent<Empty, ModelUI>, Error>(Error::NotImplementedError)
### core/embed/rust/src/ui/ui_firmware.rs
@@ -409,10 +409,8 @@ 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>>,
+ account: Option<(TString<'static>, TString<'static>)>,
+ path: Option<(TString<'static>, TString<'static>)>,
xpubs: Obj, // TODO: replace Obj
) -> Result<impl LayoutMaybeTrace, Error>;
### core/mocks/generated/trezorui_api.pyi
@@ -580,10 +580,8 @@ def show_address_details(
address: str,
case_sensitive: bool,
details_title: str,
- account_label: str,
- account: str | None,
- path_label: str,
- path: str | None,
+ account: tuple[str, str] | None,
+ path: tuple[str, str] | None,
xpubs: Sequence[tuple[str, str]],
) -> LayoutContext[UiResult]:
"""Show address details - QR code, account, path, cosigner xpubs."""
### core/src/trezor/ui/layouts/bolt/__init__.py
@@ -368,10 +368,12 @@ 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,
+ account=(with_colon(TR.words__account), account) if account else None,
+ path=(
+ (with_colon(TR.address_details__derivation_path), path)
+ if path
+ else None
+ ),
xpubs=[(xpub_title(i), xpub) for i, xpub in enumerate(xpubs)],
) as layout:
result = await interact(layout, None, raise_on_cancel=None)
### core/src/trezor/ui/layouts/caesar/__init__.py
@@ -376,10 +376,12 @@ 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,
+ account=(with_colon(TR.words__account), account) if account else None,
+ path=(
+ (with_colon(TR.address_details__derivation_path), path)
+ if path
+ else None
+ ),
xpubs=[(xpub_title(i), xpub) for i, xpub in enumerate(xpubs)],
) as layout:
result = await interact(layout, None, raise_on_cancel=None)
### core/src/trezor/wire/thp/ui.py
@@ -110,10 +110,8 @@ 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="",
+ account=None,
+ path=None,
xpubs=[],
) as layout:
return await interact(layout, br_name=None)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.