1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2025-01-03 03:50:58 +00:00

refactor(core/stellar): use semantically appropriate layouts everywhere

This commit is contained in:
matejcik 2021-07-19 15:13:57 +02:00 committed by matejcik
parent f3802dea61
commit b30c9f7584
2 changed files with 145 additions and 166 deletions

View File

@ -1,32 +1,33 @@
from trezor import strings, ui from trezor import strings, ui
from trezor.enums import ButtonRequestType from trezor.enums import ButtonRequestType
from trezor.ui.constants import MONO_ADDR_PER_LINE
from trezor.ui.layouts import ( from trezor.ui.layouts import (
confirm_action, confirm_action,
confirm_hex, confirm_address,
confirm_blob,
confirm_metadata, confirm_metadata,
confirm_timebounds_stellar, confirm_timebounds_stellar,
) )
from . import consts from . import consts
if False:
from trezor.messages import StellarAssetType
async def require_confirm_init( async def require_confirm_init(
ctx, address: str, network_passphrase: str, accounts_match: bool ctx, address: str, network_passphrase: str, accounts_match: bool
): ):
if accounts_match: if accounts_match:
description = "Initialize signing with\nyour account" description = "Initialize signing with your account"
else: else:
description = "Initialize signing with" description = "Initialize signing with"
await require_confirm_op( await confirm_address(
ctx, ctx,
"confirm_init",
title="Confirm Stellar", title="Confirm Stellar",
subtitle=None, address=address,
br_type="confirm_init",
description=description, description=description,
data=address,
icon=ui.ICON_SEND, icon=ui.ICON_SEND,
is_account=True,
) )
network = get_network_warning(network_passphrase) network = get_network_warning(network_passphrase)
@ -68,13 +69,12 @@ async def require_confirm_memo(ctx, memo_type: int, memo_text: str):
br_code=ButtonRequestType.ConfirmOutput, br_code=ButtonRequestType.ConfirmOutput,
) )
await require_confirm_op( await confirm_blob(
ctx, ctx,
"confirm_memo", "confirm_memo",
title="Confirm memo", title="Confirm memo",
subtitle=description, description=description,
data=memo_text, data=memo_text,
split=False,
) )
@ -91,39 +91,21 @@ async def require_confirm_final(ctx, fee: int, num_operations: int):
) )
async def require_confirm_op( def format_asset(asset: StellarAssetType | None = None) -> str:
ctx, if asset is None or asset.type == consts.ASSET_TYPE_NATIVE:
br_type: str, return "XLM"
subtitle: str | None, else:
data: str, return asset.code
title: str = "Confirm operation",
description: str = None,
icon=ui.ICON_CONFIRM, def format_amount(amount: int, asset: StellarAssetType | None = None) -> str:
split: bool = True, return (
is_account: bool = False, strings.format_amount(amount, consts.AMOUNT_DECIMALS)
): + " "
await confirm_hex( + format_asset(asset)
ctx,
br_type,
title=title,
subtitle=subtitle,
description=description,
data=data,
width=MONO_ADDR_PER_LINE if split else None,
icon=icon,
truncate=True,
truncate_ellipsis=".." if is_account else "",
br_code=ButtonRequestType.ConfirmOutput,
) )
def format_amount(amount: int, ticker=True) -> str:
t = ""
if ticker:
t = " XLM"
return strings.format_amount(amount, consts.AMOUNT_DECIMALS) + t
def get_network_warning(network_passphrase: str): def get_network_warning(network_passphrase: str):
if network_passphrase == consts.NETWORK_PASSPHRASE_PUBLIC: if network_passphrase == consts.NETWORK_PASSPHRASE_PUBLIC:
return None return None

View File

@ -1,6 +1,3 @@
from ubinascii import hexlify
from trezor.enums import ButtonRequestType
from trezor.messages import ( from trezor.messages import (
StellarAccountMergeOp, StellarAccountMergeOp,
StellarAllowTrustOp, StellarAllowTrustOp,
@ -15,71 +12,83 @@ from trezor.messages import (
StellarPaymentOp, StellarPaymentOp,
StellarSetOptionsOp, StellarSetOptionsOp,
) )
from trezor.ui.layouts import confirm_metadata from trezor.ui.layouts import (
confirm_address,
confirm_amount,
confirm_blob,
confirm_metadata,
confirm_output,
confirm_properties,
confirm_text,
)
from trezor.wire import ProcessError from trezor.wire import ProcessError
from .. import consts, helpers from .. import consts, helpers
from ..layout import format_amount, require_confirm_op, ui from ..layout import format_amount, format_asset
async def confirm_source_account(ctx, source_account: str): async def confirm_source_account(ctx, source_account: str):
await require_confirm_op(ctx, "confirm_source", "Source account:", source_account) await confirm_address(
ctx,
"Confirm operation",
source_account,
description="Source account:",
br_type="op_source_account",
)
async def confirm_allow_trust_op(ctx, op: StellarAllowTrustOp): async def confirm_allow_trust_op(ctx, op: StellarAllowTrustOp):
await require_confirm_op( await confirm_properties(
ctx, ctx,
"op_allow_trust", "op_allow_trust",
subtitle="Allow Trust" if op.is_authorized else "Revoke Trust", title="Allow trust" if op.is_authorized else "Revoke trust",
description="of %s by:" % op.asset_code, props=(
data=op.trusted_account, ("Asset", op.asset_code),
is_account=True, ("Trusted Account", op.trusted_account),
),
) )
async def confirm_account_merge_op(ctx, op: StellarAccountMergeOp): async def confirm_account_merge_op(ctx, op: StellarAccountMergeOp):
await require_confirm_op( await confirm_address(
ctx, ctx,
"op_merge",
"Account Merge", "Account Merge",
op.destination_account,
description="All XLM will be sent to:", description="All XLM will be sent to:",
data=op.destination_account, br_type="op_account_merge",
is_account=True,
) )
async def confirm_bump_sequence_op(ctx, op: StellarBumpSequenceOp): async def confirm_bump_sequence_op(ctx, op: StellarBumpSequenceOp):
await require_confirm_op( await confirm_metadata(
ctx, ctx,
"op_bump", "op_bump",
"Bump Sequence", "Bump Sequence",
description="Set sequence to", content="Set sequence to {}?",
data=str(op.bump_to), param=str(op.bump_to),
split=False,
) )
async def confirm_change_trust_op(ctx, op: StellarChangeTrustOp): async def confirm_change_trust_op(ctx, op: StellarChangeTrustOp):
await require_confirm_op( await confirm_amount(
ctx, ctx,
"op_change_trust", title="Delete trust" if op.limit == 0 else "Add trust",
subtitle="Delete Trust" if op.limit == 0 else "Add Trust", amount=format_amount(op.limit, op.asset),
description="Asset: %s\nAmount: %s" description="Limit:",
% (op.asset.code, format_amount(op.limit, ticker=False)), br_type="op_change_trust",
data="",
split=False,
) )
await confirm_asset_issuer(ctx, op.asset) await confirm_asset_issuer(ctx, op.asset)
async def confirm_create_account_op(ctx, op: StellarCreateAccountOp): async def confirm_create_account_op(ctx, op: StellarCreateAccountOp):
await require_confirm_op( await confirm_properties(
ctx, ctx,
"op_account", "op_create_account",
subtitle="Create Account", "Create Account",
description="with %s" % format_amount(op.starting_balance), props=(
data=op.new_account, ("Account", op.new_account),
is_account=True, ("Initial Balance", format_amount(op.starting_balance)),
),
) )
@ -104,19 +113,18 @@ async def confirm_manage_offer_op(ctx, op: StellarManageOfferOp):
async def _confirm_offer(ctx, title, op): async def _confirm_offer(ctx, title, op):
await require_confirm_op( await confirm_properties(
ctx, ctx,
"op_offer", "op_offer",
subtitle=title, title=title,
description="Sell %s %s\nFor %f\nPer %s" props=(
% ( ("Selling:", format_amount(op.amount, op.selling_asset)),
format_amount(op.amount, ticker=False), ("Buying:", format_asset(op.buying_asset)),
op.selling_asset.code, (
op.price_n / op.price_d, "Price per {}:".format(format_asset(op.buying_asset)),
format_asset_code(op.buying_asset), str(op.price_n / op.price_d),
),
), ),
data="",
split=False,
) )
await confirm_asset_issuer(ctx, op.selling_asset) await confirm_asset_issuer(ctx, op.selling_asset)
await confirm_asset_issuer(ctx, op.buying_asset) await confirm_asset_issuer(ctx, op.buying_asset)
@ -125,122 +133,117 @@ async def _confirm_offer(ctx, title, op):
async def confirm_manage_data_op(ctx, op: StellarManageDataOp): async def confirm_manage_data_op(ctx, op: StellarManageDataOp):
from trezor.crypto.hashlib import sha256 from trezor.crypto.hashlib import sha256
if op.value:
title = "Set"
else:
title = "Clear"
await require_confirm_op(ctx, "op_data", "%s data value key" % title, op.key)
if op.value: if op.value:
digest = sha256(op.value).digest() digest = sha256(op.value).digest()
digest_str = hexlify(digest).decode() await confirm_properties(
await require_confirm_op(ctx, "op_data_value", "Value (SHA-256):", digest_str) ctx,
"op_data",
"Set data",
props=(("Key:", op.key), ("Value (SHA-256):", digest)),
)
else:
await confirm_metadata(
ctx,
"op_data",
"Clear data",
"Do you want to clear value key {}?",
param=op.key,
)
async def confirm_path_payment_op(ctx, op: StellarPathPaymentOp): async def confirm_path_payment_op(ctx, op: StellarPathPaymentOp):
await require_confirm_op( await confirm_output(
ctx, ctx,
"op_path_payment", address=op.destination_account,
subtitle="Path Pay %s\n%s to:" amount=format_amount(op.destination_amount, op.destination_asset),
% ( title="Path Pay",
format_amount(op.destination_amount, ticker=False),
format_asset_code(op.destination_asset),
),
data=op.destination_account,
is_account=True,
) )
await confirm_asset_issuer(ctx, op.destination_asset) await confirm_asset_issuer(ctx, op.destination_asset)
# confirm what the sender is using to pay # confirm what the sender is using to pay
await confirm_metadata( await confirm_amount(
ctx, ctx,
"op_path_payment", title="Debited amount",
"Confirm operation", amount=format_amount(op.send_max, op.send_asset),
content="Pay using\n{}\nThis amount is debited from your account.", description="Pay at most:",
param="{}\n{}".format( br_type="op_path_payment",
format_amount(op.send_max, ticker=False),
format_asset_code(op.send_asset),
),
icon=ui.ICON_CONFIRM,
hide_continue=True,
br_code=ButtonRequestType.ConfirmOutput,
) )
await confirm_asset_issuer(ctx, op.send_asset) await confirm_asset_issuer(ctx, op.send_asset)
async def confirm_payment_op(ctx, op: StellarPaymentOp): async def confirm_payment_op(ctx, op: StellarPaymentOp):
description = "Pay {}\n{} to:".format( await confirm_output(
format_amount(op.amount, ticker=False), format_asset_code(op.asset) ctx,
address=op.destination_account,
amount=format_amount(op.amount, op.asset),
) )
await require_confirm_op(
ctx, "op_payment", description, op.destination_account, is_account=True
)
await confirm_asset_issuer(ctx, op.asset) await confirm_asset_issuer(ctx, op.asset)
async def confirm_set_options_op(ctx, op: StellarSetOptionsOp): async def confirm_set_options_op(ctx, op: StellarSetOptionsOp):
if op.inflation_destination_account: if op.inflation_destination_account:
await require_confirm_op( await confirm_address(
ctx, ctx,
"op_inflation", "Inflation",
"Set Inflation Destination",
op.inflation_destination_account, op.inflation_destination_account,
description="Destination:",
br_type="op_inflation",
) )
if op.clear_flags: if op.clear_flags:
t = _format_flags(op.clear_flags) t = _format_flags(op.clear_flags)
await require_confirm_op(ctx, "op_clear_flags", "Clear Flags", t, split=False) await confirm_text(ctx, "op_set_options", "Clear flags", data=t)
if op.set_flags: if op.set_flags:
t = _format_flags(op.set_flags) t = _format_flags(op.set_flags)
await require_confirm_op(ctx, "op_set_flags", "Set Flags", t, split=False) await confirm_text(ctx, "op_set_options", "Set flags", data=t)
thresholds = _format_thresholds(op) thresholds = _format_thresholds(op)
if thresholds: if thresholds:
await require_confirm_op( await confirm_properties(
ctx, ctx, "op_thresholds", "Account Thresholds", props=thresholds
"op_thresholds",
"Account Thresholds",
thresholds,
split=False,
) )
if op.home_domain: if op.home_domain:
await require_confirm_op(ctx, "op_home_domain", "Home Domain", op.home_domain) await confirm_text(ctx, "op_home_domain", "Home Domain", op.home_domain)
if op.signer_type is not None: if op.signer_type is not None:
if op.signer_weight > 0: if op.signer_weight > 0:
t = "Add Signer (%s)" title = "Add Signer"
else: else:
t = "Remove Signer (%s)" title = "Remove Signer"
data: str | bytes = ""
if op.signer_type == consts.SIGN_TYPE_ACCOUNT: if op.signer_type == consts.SIGN_TYPE_ACCOUNT:
await require_confirm_op( description = "Account:"
ctx, data = helpers.address_from_public_key(op.signer_key)
"op_signer", elif op.signer_type == consts.SIGN_TYPE_PRE_AUTH:
t % "acc", description = "Pre-auth transaction:"
helpers.address_from_public_key(op.signer_key), data = op.signer_key
) elif op.signer_type == consts.SIGN_TYPE_HASH:
elif op.signer_type in (consts.SIGN_TYPE_PRE_AUTH, consts.SIGN_TYPE_HASH): description = "Hash:"
if op.signer_type == consts.SIGN_TYPE_PRE_AUTH: data = op.signer_key
signer_type = "auth"
else:
signer_type = "hash"
await require_confirm_op(
ctx,
"op_signer",
t % signer_type,
hexlify(op.signer_key).decode(),
)
else: else:
raise ProcessError("Stellar: invalid signer type") raise ProcessError("Stellar: invalid signer type")
await confirm_blob(
ctx,
"op_signer",
title=title,
description=description,
data=data,
)
def _format_thresholds(op: StellarSetOptionsOp) -> tuple:
text = "" def _format_thresholds(op: StellarSetOptionsOp) -> list[(str, str)]:
props = []
if op.master_weight is not None: if op.master_weight is not None:
text += "Master Weight: %d\n" % op.master_weight props.append(("Master Weight:", str(op.master_weight)))
if op.low_threshold is not None: if op.low_threshold is not None:
text += "Low: %d\n" % op.low_threshold props.append(("Low:", str(op.low_threshold)))
if op.medium_threshold is not None: if op.medium_threshold is not None:
text += "Medium: %d\n" % op.medium_threshold props.append(("Medium:", str(op.medium_threshold)))
if op.high_threshold is not None: if op.high_threshold is not None:
text += "High: %d\n" % op.high_threshold props.append(("High:", str(op.high_threshold)))
return text return props
def _format_flags(flags: int) -> tuple: def _format_flags(flags: int) -> tuple:
@ -254,19 +257,13 @@ def _format_flags(flags: int) -> tuple:
return text return text
def format_asset_code(asset: StellarAssetType) -> str:
if asset is None or asset.type == consts.ASSET_TYPE_NATIVE:
return "XLM (native)"
return asset.code
async def confirm_asset_issuer(ctx, asset: StellarAssetType): async def confirm_asset_issuer(ctx, asset: StellarAssetType):
if asset is None or asset.type == consts.ASSET_TYPE_NATIVE: if asset is None or asset.type == consts.ASSET_TYPE_NATIVE:
return return
await require_confirm_op( await confirm_address(
ctx, ctx,
"confirm_issuer", "Confirm Issuer",
title="Confirm issuer", asset.issuer,
subtitle="%s issuer:" % asset.code, description="{} issuer:".format(asset.code),
data=asset.issuer, br_type="confirm_asset_issuer",
) )