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:
parent
f3802dea61
commit
b30c9f7584
@ -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
|
||||||
|
@ -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",
|
||||||
)
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user