1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2025-03-03 16:56:07 +00:00

refactor(core): convert apps.nem to layouts

This commit is contained in:
Martin Milata 2021-03-12 13:05:38 +01:00 committed by matejcik
parent dd3b689ded
commit 178b575465
7 changed files with 142 additions and 153 deletions

View File

@ -1,39 +1,50 @@
from trezor import ui
from trezor.enums import ButtonRequestType from trezor.enums import ButtonRequestType
from trezor.strings import format_amount from trezor.strings import format_amount
from trezor.ui.components.tt.text import Text from trezor.ui.layouts import confirm_metadata, confirm_properties
from apps.common.confirm import require_confirm, require_hold_to_confirm
from .helpers import NEM_MAX_DIVISIBILITY from .helpers import NEM_MAX_DIVISIBILITY
async def require_confirm_text(ctx, action: str): async def require_confirm_text(ctx, action: str):
text = Text("Confirm action", ui.ICON_SEND, ui.GREEN, new_lines=False) await confirm_metadata(
text.normal(action) ctx,
await require_confirm(ctx, text, ButtonRequestType.ConfirmOutput) "confirm_nem",
title="Confirm action",
content=action,
hide_continue=True,
br_code=ButtonRequestType.ConfirmOutput,
)
async def require_confirm_fee(ctx, action: str, fee: int): async def require_confirm_fee(ctx, action: str, fee: int):
content = ( await confirm_metadata(
ui.NORMAL, ctx,
action, "confirm_fee",
ui.BOLD, title="Confirm fee",
"%s XEM" % format_amount(fee, NEM_MAX_DIVISIBILITY), content=action + "\n{}",
param="{} XEM".format(format_amount(fee, NEM_MAX_DIVISIBILITY)),
hide_continue=True,
br_code=ButtonRequestType.ConfirmOutput,
) )
await require_confirm_content(ctx, "Confirm fee", content)
async def require_confirm_content(ctx, headline: str, content: list): async def require_confirm_content(ctx, headline: str, content: list):
text = Text(headline, ui.ICON_SEND, ui.GREEN) await confirm_properties(
text.normal(*content) ctx,
await require_confirm(ctx, text, ButtonRequestType.ConfirmOutput) "confirm_content",
title=headline,
props=content,
)
async def require_confirm_final(ctx, fee: int): async def require_confirm_final(ctx, fee: int):
text = Text("Final confirm", ui.ICON_SEND, ui.GREEN)
text.normal("Sign this transaction")
text.bold("and pay %s XEM" % format_amount(fee, NEM_MAX_DIVISIBILITY))
text.normal("for network fee?")
# we use SignTx, not ConfirmOutput, for compatibility with T1 # we use SignTx, not ConfirmOutput, for compatibility with T1
await require_hold_to_confirm(ctx, text, ButtonRequestType.SignTx) await confirm_metadata(
ctx,
"confirm_final",
title="Final confirm",
content="Sign this transaction\n{}\nfor network fee?",
param="and pay {} XEM".format(format_amount(fee, NEM_MAX_DIVISIBILITY)),
hide_continue=True,
hold=True,
)

View File

@ -1,16 +1,12 @@
from trezor import ui from trezor import ui
from trezor.enums import ButtonRequestType, NEMMosaicLevy, NEMSupplyChangeType from trezor.enums import NEMMosaicLevy, NEMSupplyChangeType
from trezor.messages import ( from trezor.messages import (
NEMMosaicCreation, NEMMosaicCreation,
NEMMosaicDefinition, NEMMosaicDefinition,
NEMMosaicSupplyChange, NEMMosaicSupplyChange,
NEMTransactionCommon, NEMTransactionCommon,
) )
from trezor.ui.components.tt.scroll import Paginated from trezor.ui.layouts import confirm_properties
from trezor.ui.components.tt.text import Text
from apps.common.confirm import require_confirm
from apps.common.layout import split_address
from ..layout import ( from ..layout import (
require_confirm_content, require_confirm_content,
@ -47,27 +43,15 @@ async def ask_supply_change(
def _creation_message(mosaic_creation): def _creation_message(mosaic_creation):
return [ return [
ui.NORMAL, ("Create mosaic", mosaic_creation.definition.mosaic),
"Create mosaic", ("under namespace", mosaic_creation.definition.namespace),
ui.BOLD,
mosaic_creation.definition.mosaic,
ui.NORMAL,
"under namespace",
ui.BOLD,
mosaic_creation.definition.namespace,
] ]
def _supply_message(supply_change): def _supply_message(supply_change):
return [ return [
ui.NORMAL, ("Modify supply for", supply_change.mosaic),
"Modify supply for", ("under namespace", supply_change.namespace),
ui.BOLD,
supply_change.mosaic,
ui.NORMAL,
"under namespace",
ui.BOLD,
supply_change.namespace,
] ]
@ -76,21 +60,14 @@ async def require_confirm_properties(ctx, definition: NEMMosaicDefinition):
# description # description
if definition.description: if definition.description:
t = Text("Confirm properties", ui.ICON_SEND, new_lines=False) properties.append(("Description:", definition.description))
t.bold("Description:")
t.br()
t.normal(*definition.description.split(" "))
properties.append(t)
# transferable # transferable
if definition.transferable: if definition.transferable:
transferable = "Yes" transferable = "Yes"
else: else:
transferable = "No" transferable = "No"
t = Text("Confirm properties", ui.ICON_SEND) properties.append(("Transferable?", transferable))
t.bold("Transferable?")
t.normal(transferable)
properties.append(t)
# mutable_supply # mutable_supply
if definition.mutable_supply: if definition.mutable_supply:
@ -98,45 +75,30 @@ async def require_confirm_properties(ctx, definition: NEMMosaicDefinition):
else: else:
imm = "immutable" imm = "immutable"
if definition.supply: if definition.supply:
t = Text("Confirm properties", ui.ICON_SEND) properties.append(("Initial supply:", str(definition.supply) + "\n" + imm))
t.bold("Initial supply:")
t.normal(str(definition.supply), imm)
else: else:
t = Text("Confirm properties", ui.ICON_SEND) properties.append(("Initial supply:", imm))
t.bold("Initial supply:")
t.normal(imm)
properties.append(t)
# levy # levy
if definition.levy: if definition.levy:
properties.append(("Levy recipient:", definition.levy_address))
t = Text("Confirm properties", ui.ICON_SEND) properties.append(("Levy fee:", str(definition.fee)))
t.bold("Levy recipient:") properties.append(("Levy divisibility:", str(definition.divisibility)))
t.mono(*split_address(definition.levy_address))
properties.append(t)
t = Text("Confirm properties", ui.ICON_SEND) properties.append(("Levy namespace:", definition.levy_namespace))
t.bold("Levy fee:") properties.append(("Levy mosaic:", definition.levy_mosaic))
t.normal(str(definition.fee))
t.bold("Levy divisibility:")
t.normal(str(definition.divisibility))
properties.append(t)
t = Text("Confirm properties", ui.ICON_SEND)
t.bold("Levy namespace:")
t.normal(definition.levy_namespace)
t.bold("Levy mosaic:")
t.normal(definition.levy_mosaic)
properties.append(t)
if definition.levy == NEMMosaicLevy.MosaicLevy_Absolute: if definition.levy == NEMMosaicLevy.MosaicLevy_Absolute:
levy_type = "absolute" levy_type = "absolute"
else: else:
levy_type = "percentile" levy_type = "percentile"
t = Text("Confirm properties", ui.ICON_SEND) properties.append(("Levy type:", levy_type))
t.bold("Levy type:")
t.normal(levy_type)
properties.append(t)
paginated = Paginated(properties) await confirm_properties(
await require_confirm(ctx, paginated, ButtonRequestType.ConfirmOutput) ctx,
"confirm_properties",
title="Confirm properties",
props=properties,
icon_color=ui.ORANGE_ICON,
)

View File

@ -2,16 +2,10 @@ from trezor import ui
from trezor.crypto import nem from trezor.crypto import nem
from trezor.enums import ButtonRequestType, NEMModificationType from trezor.enums import ButtonRequestType, NEMModificationType
from trezor.messages import NEMAggregateModification, NEMSignTx, NEMTransactionCommon from trezor.messages import NEMAggregateModification, NEMSignTx, NEMTransactionCommon
from trezor.ui.components.tt.text import Text from trezor.ui.constants import MONO_ADDR_PER_LINE
from trezor.ui.layouts import confirm_hex
from apps.common.layout import split_address from ..layout import require_confirm_fee, require_confirm_final, require_confirm_text
from ..layout import (
require_confirm,
require_confirm_fee,
require_confirm_final,
require_confirm_text,
)
async def ask_multisig(ctx, msg: NEMSignTx): async def ask_multisig(ctx, msg: NEMSignTx):
@ -48,7 +42,14 @@ async def ask_aggregate_modification(
async def _require_confirm_address(ctx, action: str, address: str): async def _require_confirm_address(ctx, action: str, address: str):
text = Text("Confirm address", ui.ICON_SEND, ui.GREEN) await confirm_hex(
text.normal(action) ctx,
text.mono(*split_address(address)) br_type="confirm_multisig",
await require_confirm(ctx, text, ButtonRequestType.ConfirmOutput) title="Confirm address",
description=action,
data=address,
br_code=ButtonRequestType.ConfirmOutput,
icon=ui.ICON_SEND,
width=MONO_ADDR_PER_LINE,
truncate=True,
)

View File

@ -1,4 +1,3 @@
from trezor import ui
from trezor.messages import NEMProvisionNamespace, NEMTransactionCommon from trezor.messages import NEMProvisionNamespace, NEMTransactionCommon
from ..layout import require_confirm_content, require_confirm_fee, require_confirm_final from ..layout import require_confirm_content, require_confirm_fee, require_confirm_final
@ -8,19 +7,13 @@ async def ask_provision_namespace(
ctx, common: NEMTransactionCommon, namespace: NEMProvisionNamespace ctx, common: NEMTransactionCommon, namespace: NEMProvisionNamespace
): ):
if namespace.parent: if namespace.parent:
content = ( content = [
ui.NORMAL, ("Create namespace", namespace.namespace),
"Create namespace", ("under namespace", namespace.parent),
ui.BOLD, ]
namespace.namespace,
ui.NORMAL,
"under namespace",
ui.BOLD,
namespace.parent,
)
await require_confirm_content(ctx, "Confirm namespace", content) await require_confirm_content(ctx, "Confirm namespace", content)
else: else:
content = (ui.NORMAL, "Create namespace", ui.BOLD, namespace.namespace) content = [("Create namespace", namespace.namespace)]
await require_confirm_content(ctx, "Confirm namespace", content) await require_confirm_content(ctx, "Confirm namespace", content)
await require_confirm_fee(ctx, "Confirm rental fee", namespace.fee) await require_confirm_fee(ctx, "Confirm rental fee", namespace.fee)

View File

@ -7,10 +7,7 @@ from trezor.messages import (
NEMTransfer, NEMTransfer,
) )
from trezor.strings import format_amount from trezor.strings import format_amount
from trezor.ui.components.tt.text import Text from trezor.ui.layouts import confirm_action, confirm_output, confirm_properties
from apps.common.confirm import require_confirm
from apps.common.layout import split_address
from ..helpers import ( from ..helpers import (
NEM_LEVY_PERCENTILE_DIVISOR_ABSOLUTE, NEM_LEVY_PERCENTILE_DIVISOR_ABSOLUTE,
@ -46,37 +43,52 @@ async def ask_transfer_mosaic(
mosaic_quantity = mosaic.quantity * transfer.amount / NEM_MOSAIC_AMOUNT_DIVISOR mosaic_quantity = mosaic.quantity * transfer.amount / NEM_MOSAIC_AMOUNT_DIVISOR
if definition: if definition:
msg = Text("Confirm mosaic", ui.ICON_SEND, ui.GREEN) await confirm_properties(
msg.normal("Confirm transfer of") ctx,
msg.bold( "confirm_mosaic",
title="Confirm mosaic",
props=[
(
"Confirm transfer of",
format_amount(mosaic_quantity, definition["divisibility"]) format_amount(mosaic_quantity, definition["divisibility"])
+ definition["ticker"] + definition["ticker"],
),
("of", definition["name"]),
],
) )
msg.normal("of")
msg.bold(definition["name"])
await require_confirm(ctx, msg, ButtonRequestType.ConfirmOutput)
if "levy" in definition and "fee" in definition: if "levy" in definition and "fee" in definition:
levy_msg = _get_levy_msg(definition, mosaic_quantity, common.network) levy_msg = _get_levy_msg(definition, mosaic_quantity, common.network)
msg = Text("Confirm mosaic", ui.ICON_SEND, ui.GREEN) await confirm_properties(
msg.normal("Confirm mosaic", "levy fee of") ctx,
msg.bold(levy_msg) "confirm_mosaic_levy",
await require_confirm(ctx, msg, ButtonRequestType.ConfirmOutput) title="Confirm mosaic",
props=[
("Confirm mosaic\nlevy fee of", levy_msg),
],
)
else: else:
msg = Text("Confirm mosaic", ui.ICON_SEND, ui.RED) await confirm_action(
msg.bold("Unknown mosaic!") ctx,
msg.normal("Divisibility and levy") "confirm_mosaic_unknown",
msg.normal("cannot be shown for") title="Confirm mosaic",
msg.normal("unknown mosaics") action="Unknown mosaic!",
await require_confirm(ctx, msg, ButtonRequestType.ConfirmOutput) description="Divisibility and levy cannot be shown for unknown mosaics",
icon=ui.ICON_SEND,
icon_color=ui.RED,
br_code=ButtonRequestType.ConfirmOutput,
)
msg = Text("Confirm mosaic", ui.ICON_SEND, ui.GREEN) await confirm_properties(
msg.normal("Confirm transfer of") ctx,
msg.bold("%s raw units" % mosaic_quantity) "confirm_mosaic_transfer",
msg.normal("of") title="Confirm mosaic",
msg.bold("%s.%s" % (mosaic.namespace, mosaic.mosaic)) props=[
await require_confirm(ctx, msg, ButtonRequestType.ConfirmOutput) ("Confirm transfer of", "%s raw units" % mosaic_quantity),
("of", "%s.%s" % (mosaic.namespace, mosaic.mosaic)),
],
)
def _get_xem_amount(transfer: NEMTransfer): def _get_xem_amount(transfer: NEMTransfer):
@ -119,22 +131,27 @@ async def ask_importance_transfer(
async def _require_confirm_transfer(ctx, recipient, value): async def _require_confirm_transfer(ctx, recipient, value):
text = Text("Confirm transfer", ui.ICON_SEND, ui.GREEN) await confirm_output(
text.bold("Send %s XEM" % format_amount(value, NEM_MAX_DIVISIBILITY)) ctx,
text.normal("to") recipient,
text.mono(*split_address(recipient)) amount="Send {} XEM".format(format_amount(value, NEM_MAX_DIVISIBILITY)),
await require_confirm(ctx, text, ButtonRequestType.ConfirmOutput) font_amount=ui.BOLD,
title="Confirm transfer",
to_str="\nto\n",
)
async def _require_confirm_payload(ctx, payload: bytearray, encrypt=False): async def _require_confirm_payload(ctx, payload: bytearray, encrypt=False):
payload = bytes(payload).decode() payload = bytes(payload).decode()
subtitle = "Encrypted:" if encrypt else "Unencrypted:"
if encrypt: await confirm_properties(
text = Text("Confirm payload", ui.ICON_SEND, ui.GREEN) ctx,
text.bold("Encrypted:") "confirm_payload",
text.normal(payload) title="Confirm payload",
else: props=[
text = Text("Confirm payload", ui.ICON_SEND, ui.RED) (None, subtitle),
text.bold("Unencrypted:") (payload, None),
text.normal(payload) ],
await require_confirm(ctx, text, ButtonRequestType.ConfirmOutput) icon_color=ui.GREEN if encrypt else ui.RED,
)

View File

@ -36,7 +36,7 @@ if False:
) )
ExceptionType = Union[BaseException, Type[BaseException]] ExceptionType = Union[BaseException, Type[BaseException]]
PropertyType = Tuple[str, Optional[str]] PropertyType = Tuple[Optional[str], Optional[str]]
__all__ = ( __all__ = (
@ -590,6 +590,7 @@ async def confirm_properties(
) -> None: ) -> None:
para = [] para = []
for p in props: for p in props:
if p[0] is not None:
para.append((ui.NORMAL, p[0])) para.append((ui.NORMAL, p[0]))
if p[1] is not None: if p[1] is not None:
para.append((ui.BOLD, p[1])) para.append((ui.BOLD, p[1]))

View File

@ -28,10 +28,14 @@ class TestMsgNEMGetaddress:
@pytest.mark.setup_client(mnemonic=MNEMONIC12) @pytest.mark.setup_client(mnemonic=MNEMONIC12)
def test_nem_getaddress(self, client): def test_nem_getaddress(self, client):
assert ( assert (
nem.get_address(client, parse_path("m/44'/1'/0'/0'/0'"), 0x68) nem.get_address(
client, parse_path("m/44'/1'/0'/0'/0'"), 0x68, show_display=True
)
== "NB3JCHVARQNGDS3UVGAJPTFE22UQFGMCQGHUBWQN" == "NB3JCHVARQNGDS3UVGAJPTFE22UQFGMCQGHUBWQN"
) )
assert ( assert (
nem.get_address(client, parse_path("m/44'/1'/0'/0'/0'"), 0x98) nem.get_address(
client, parse_path("m/44'/1'/0'/0'/0'"), 0x98, show_display=True
)
== "TB3JCHVARQNGDS3UVGAJPTFE22UQFGMCQHSBNBMF" == "TB3JCHVARQNGDS3UVGAJPTFE22UQFGMCQHSBNBMF"
) )