refactor(core): move the multisig XPUB title into a translation template
What changed, and why it matters
This commit is a straightforward code cleanup: it moves the on-screen title for multisig XPUB screens from hard-coded English text into the device's translation system. The visible text remains essentially the same, and there is no security change.
No security action required. This is a localization refactor with no functional or security impact.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The change refactors the xpub_title() helper in four UI layout implementations (bolt, caesar, delizia, eckhart) to use a new translation key address__title_multisig_xpub_template instead of an inline f-string. It adds the key to the Rust translation constants, mock stubs, English translation file, and ordering/signature metadata. A test assertion is updated to match the new translation-based formatting. No logic, validation, or cryptographic behavior is altered.
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__.pycore/translations/en.jsoncore/translations/order.jsoncore/translations/signatures.jsoncore/embed/rust/librust_qstr.hcore/embed/rust/src/translations/generated/translated_string.rscore/mocks/trezortranslate_keys.pyitests/input_flows.pyInspect captured patch +20279 / −20239
### core/embed/rust/librust_qstr.h
@@ -121,6 +121,7 @@ static void _librust_qstrs(void) {
MP_QSTR_address__qr_code;
MP_QSTR_address__title_cosigner;
MP_QSTR_address__title_cosigner_template;
+ MP_QSTR_address__title_multisig_xpub_template;
MP_QSTR_address__title_provider_address;
MP_QSTR_address__title_receive_address;
MP_QSTR_address__title_refund_address;
### core/embed/rust/src/translations/generated/translated_string.rs
[binary or diff unavailable]
### core/mocks/trezortranslate_keys.pyi
@@ -16,12 +16,13 @@ class TR:
address__public_key: str = "Public key"
address__public_key_confirmed: str = "Public key confirmed"
address__qr_code: str = "QR code"
- address__title_cosigner: str = "Cosigner"
+ address__title_cosigner: str = "(cosigner)"
address__title_cosigner_template: str = "Cosigner {0}"
+ address__title_multisig_xpub_template: str = "Multisig XPUB #{0} "
address__title_provider_address: str = "Provider address"
address__title_receive_address: str = "Receive address"
address__title_refund_address: str = "Refund address"
- address__title_yours: str = "Yours"
+ address__title_yours: str = "(yours)"
address__warning_not_yours: str = "This is NOT your address"
address__xpub: str = "XPUB"
address_details__account_info: str = "Account info"
### core/src/trezor/ui/layouts/bolt/__init__.py
@@ -355,7 +355,7 @@ async def show_address(
elif result is INFO:
def xpub_title(i: int) -> str:
- result = f"MULTISIG XPUB #{i + 1}\n"
+ result = TR.address__title_multisig_xpub_template.format(i + 1)
result += (
TR.address__title_yours
if i == multisig_index
### core/src/trezor/ui/layouts/caesar/__init__.py
@@ -363,7 +363,7 @@ async def show_address(
def xpub_title(i: int) -> str:
# Will be marquee (cannot fit one line)
- result = f"MULTISIG XPUB #{i + 1} "
+ result = TR.address__title_multisig_xpub_template.format(i + 1)
result += (
TR.address__title_yours
if i == multisig_index
### core/src/trezor/ui/layouts/delizia/__init__.py
@@ -329,7 +329,7 @@ async def show_address(
chunkify: bool = False,
) -> None:
def xpub_title(i: int) -> str:
- result = f"Multisig XPUB #{i + 1}\n"
+ result = TR.address__title_multisig_xpub_template.format(i + 1)
result += (
TR.address__title_yours
if i == multisig_index
### core/src/trezor/ui/layouts/eckhart/__init__.py
@@ -284,7 +284,7 @@ async def show_address(
chunkify: bool = False,
) -> None:
def xpub_title(i: int) -> str:
- result = f"Multisig XPUB #{i + 1}\n"
+ result = TR.address__title_multisig_xpub_template.format(i + 1)
result += (
TR.address__title_yours
if i == multisig_index
### core/translations/en.json
@@ -50,6 +50,7 @@
"address__qr_code": "QR code",
"address__title_cosigner": "(cosigner)",
"address__title_cosigner_template": "Cosigner {0}",
+ "address__title_multisig_xpub_template": "Multisig XPUB #{0} ",
"address__title_provider_address": "Provider address",
"address__title_receive_address": "Receive address",
"address__title_refund_address": "Refund address",
### core/translations/order.json
@@ -1294,5 +1294,6 @@
"1292": "words__from_title",
"1293": "words__undelegate",
"1294": "buttons__review",
- "1295": "buttons__cancel_sign"
+ "1295": "buttons__cancel_sign",
+ "1296": "address__title_multisig_xpub_template"
}
### core/translations/signatures.json
@@ -1,8 +1,8 @@
{
"current": {
- "merkle_root": "ac262fd148a0cf046bdc8d6f3a0cd5b65e23a77e5e01fc8d983b53a5f7802110",
- "datetime": "2026-09-20T15:23:23.511849+00:00",
- "commit": "e9a7a2bc8be56832100e8a352b8dfea3eedad733"
+ "merkle_root": "555af5ef0e8212359f75f94b53357dc8bb7ebcc8231859e38326fd8edfac431a",
+ "datetime": "2026-09-21T14:16:33.405107+00:00",
+ "commit": "80c621ed0b87dcaf65804d1a72e81385deed8fc7"
},
"history": [
{
### tests/input_flows.py
@@ -694,7 +694,9 @@ def __init__(
self.index = index
def _assert_xpub_title(self, title: str, xpub_num: int) -> None:
- expected_title = f"MULTISIG XPUB #{xpub_num + 1}"
+ expected_title = TR.format(
+ "address__title_multisig_xpub_template", xpub_num + 1
+ )
assert expected_title in title
if self.index == xpub_num:
assert TR.address__title_yours in titleWhy 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.