mirror of
https://github.com/SeedSigner/seedsigner.git
synced 2026-09-14 04:45:08 +00:00
refactor(l10n): make multisig wallet policy display translatable
This commit is contained in:
+11
-1
@@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: seedsigner 0.8.6\n"
|
||||
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
||||
"POT-Creation-Date: 2026-02-16 21:42+0000\n"
|
||||
"POT-Creation-Date: 2026-02-19 07:41+0000\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
@@ -1340,6 +1340,11 @@ msgstr ""
|
||||
msgid "Verify addr"
|
||||
msgstr ""
|
||||
|
||||
#. Multisig policy display showing signing threshold (e.g. "2 of 3")
|
||||
#: src/seedsigner/views/seed_views.py
|
||||
msgid "{threshold} of {n}"
|
||||
msgstr ""
|
||||
|
||||
#: src/seedsigner/views/seed_views.py
|
||||
msgid "Signing messages for custom derivation paths not supported"
|
||||
msgstr ""
|
||||
@@ -1466,6 +1471,11 @@ msgstr ""
|
||||
msgid "Change addresses"
|
||||
msgstr ""
|
||||
|
||||
#. Multisig wallet policy display (e.g. "2 / 3 multisig")
|
||||
#: src/seedsigner/views/tools_views.py
|
||||
msgid "{threshold} / {n} multisig"
|
||||
msgstr ""
|
||||
|
||||
#. a status message that our payment addresses are being calculated
|
||||
#: src/seedsigner/views/tools_views.py
|
||||
msgid "Calculating addrs..."
|
||||
|
||||
@@ -489,7 +489,7 @@ class ToolsAddressExplorerAddressTypeScreen(ButtonListScreen):
|
||||
self.components.append(IconTextLine(
|
||||
# TRANSLATOR_NOTE: a label for a BIP-380-ish Output Descriptor
|
||||
label_text=_("Wallet descriptor"),
|
||||
value_text=self.wallet_descriptor_display_name, # TODO: English text from embit (e.g. "1 / 2 multisig"); make l10 friendly
|
||||
value_text=self.wallet_descriptor_display_name,
|
||||
is_text_centered=True,
|
||||
screen_x=GUIConstants.EDGE_PADDING,
|
||||
screen_y=self.top_nav.height + GUIConstants.COMPONENT_PADDING,
|
||||
|
||||
@@ -104,6 +104,14 @@ def get_multisig_address(descriptor: Descriptor, index: int = 0, is_change: bool
|
||||
|
||||
|
||||
|
||||
def get_multisig_policy(descriptor: Descriptor) -> tuple:
|
||||
"""Extract (threshold, n) from a basic multisig descriptor."""
|
||||
if not descriptor.is_basic_multisig:
|
||||
raise ValueError(f"Expected a basic multisig descriptor, got: {descriptor.brief_policy}")
|
||||
return (str(descriptor.miniscript.args[0]), str(len(descriptor.keys)))
|
||||
|
||||
|
||||
|
||||
def get_embit_network_name(settings_name):
|
||||
""" Convert SeedSigner SettingsConstants for `network` to embit's NETWORK key """
|
||||
lookup = {
|
||||
|
||||
@@ -2068,8 +2068,10 @@ class MultisigWalletDescriptorView(View):
|
||||
fingerprint = hexlify(key.fingerprint).decode()
|
||||
fingerprints.append(fingerprint)
|
||||
|
||||
policy = descriptor.brief_policy.split("multisig")[0].strip()
|
||||
# policy = " / ".join(policy.split(" of ")) # i18n w/o l10n since coming from non-l10n embit
|
||||
from seedsigner.helpers.embit_utils import get_multisig_policy
|
||||
threshold, n = get_multisig_policy(descriptor)
|
||||
# TRANSLATOR_NOTE: Multisig policy display showing signing threshold (e.g. "2 of 3")
|
||||
policy = _("{threshold} of {n}").format(threshold=threshold, n=n)
|
||||
|
||||
button_data = [self.OK]
|
||||
if self.controller.resume_main_flow:
|
||||
|
||||
@@ -599,8 +599,12 @@ class ToolsAddressExplorerAddressTypeView(View):
|
||||
|
||||
wallet_descriptor_display_name = None
|
||||
if "wallet_descriptor" in data:
|
||||
wallet_descriptor_display_name = data["wallet_descriptor"].brief_policy.replace(" (sorted)", "")
|
||||
wallet_descriptor_display_name = " / ".join(wallet_descriptor_display_name.split(" of ")) # i18n w/o l10n since coming from non-l10n embit
|
||||
from seedsigner.helpers.embit_utils import get_multisig_policy
|
||||
threshold, n = get_multisig_policy(data["wallet_descriptor"])
|
||||
# TRANSLATOR_NOTE: Multisig wallet policy display (e.g. "2 / 3 multisig")
|
||||
wallet_descriptor_display_name = _("{threshold} / {n} multisig").format(
|
||||
threshold=threshold, n=n
|
||||
)
|
||||
|
||||
script_type = data["script_type"] if "script_type" in data else None
|
||||
|
||||
|
||||
@@ -345,6 +345,35 @@ def test_get_multisig_address():
|
||||
func(descriptor=descriptor, index=args[1], is_change=args[2], embit_network=args[3])
|
||||
|
||||
|
||||
def test_get_multisig_policy():
|
||||
"""
|
||||
tests seedsigner.helpers.embit_utils.get_multisig_policy()
|
||||
"""
|
||||
from embit.descriptor import Descriptor
|
||||
|
||||
# Reuses the same 2-of-3 multisig descriptors from test_get_multisig_address
|
||||
vectors_descriptor_expected = {
|
||||
# native segwit 2-of-3
|
||||
"wsh(sortedmulti(2,[8d55ff0d/48h/1h/0h/2h]tpubDDxNVWk924RTUhdkVB2uLHw1hGMPNMGufpZefhkkswjbZppVZcuMdjYKQN4ewUog9vbL6RBLFPRWcgTGT7kYP79N6thyJ43ELUs4N2szXMg/{0,1}/*,[73c5da0a/48h/1h/0h/2h]tpubDFH9dgzveyD8zTbPUFuLrGmCydNvxehyNdUXKJAQN8x4aZ4j6UZqGfnqFrD4NqyaTVGKbvEW54tsvPTK2UoSbCC1PJY8iCNiwTL3RWZEheQ/{0,1}/*,[0be174ee/48h/1h/0h/2h]tpubDEsePyLPkbxbrDiZSTTWdsviiNtiQjrvvzZnkLtG72QYLBygEsXePRsTdXi8DeMA7taCuuvoEBjUAfFrsNZeQJqfvG9fFoujYWbFPYUn7ux/{0,1}/*))#zw6cnrlk": ("2", "3"),
|
||||
# nested segwit 2-of-3
|
||||
"sh(wsh(sortedmulti(2,[73c5da0a/48h/1h/1h/0h/1h]tpubDFH9dgzveyD8yHQb8VrpG8FYAuwcLMHMje2CCcbBo1FpaGzYVtJeYYxcYgRqSTta5utUFts8nPPHs9C2bqoxrey5jia6Dwf9mpwrPq7YvcJ/{0,1}/*,[0be174ee/48h/1h/0h/1h]tpubDEsePyLPkbxbnj6XuKvWwdERHaKkikZxaGJ9sJqmM7okbZXgkNSFiGU6GX6qEes6kD8f9Z9FosYB9UEnBSgBEyEwwJhj4uUcFE1WE8VtKoh/{0,1}/*,[8d55ff0d/48h/1h/0h/1h]tpubDDxNVWk924RTT3vyGLHdSDoZ2JUVX7jUsPcwCQ9MrKHAtJrW5zECTF9rFHCvqu526E4PjHp61hBknts2c5aGexvX7hvCZ8TGPvQFdzxxy59/{0,1}/*)))#2ujlfp73": ("2", "3"),
|
||||
# legacy p2sh 2-of-3
|
||||
"sh(sortedmulti(2,[8d55ff0d/45h]tpubDANogJ2yfnizHwX7fSi5kUVzybyuPXDhgHB2TR9TUvkSLZFW73cRq4STKFDpx7qjJJiisyq82tbu4CeiYtmKEmT1xoCq9P8BPvXV31HUh6d/{0,1}/*,[0be174ee/45h]tpubDBkeVF2tDNT1Pz7L47iJeBB6RokU12LX6x4E6Ph8T89hmjQfB77q1AMyGwL8qpREVGq9sCJEbWwmnemwNTxnpxGn1di7BGy8jx9wEi5Vahu/{0,1}/*,[73c5da0a/45h]tpubDBKsGC1UqBDNvx9aivFmxZNgeZTUnmsCFGhWrqkLzucUCDePvbWWm3n8tAaAwMmxBG2ihdKCG9fzBdUnMxKx5PrkiqSZFi6Vkv6msUs9ddN/{0,1}/*))#p5t8sa8c": ("2", "3"),
|
||||
}
|
||||
|
||||
for desc_str, (expected_threshold, expected_n) in vectors_descriptor_expected.items():
|
||||
descriptor = Descriptor.from_string(desc_str)
|
||||
threshold, n = embit_utils.get_multisig_policy(descriptor)
|
||||
assert threshold == expected_threshold
|
||||
assert n == expected_n
|
||||
|
||||
# Non-multisig descriptor should raise ValueError
|
||||
with pytest.raises(ValueError):
|
||||
embit_utils.get_multisig_policy(Descriptor.from_string(
|
||||
"wpkh([73c5da0a/84h/1h/0h]tpubDC5FSnBiZDMmhiuCmWAYsLwgLYrrT9rAqvTySfuCCrgsWz8wxMXUS9Tb9iVMvcRbvFcAHGkMD5Kx8koh4GquNGNTfohfk7pgjhaPCdXpoba/{0,1}/*)#2aj6cvca"
|
||||
))
|
||||
|
||||
|
||||
def test_parse_derivation_path():
|
||||
# Shouldn't care if input uses "'" or "h"
|
||||
derivation_path = "m/84'/0'/0'/0/0"
|
||||
|
||||
Reference in New Issue
Block a user