mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-12-16 11:28:14 +00:00
nem: layout refactoring and fixes
This commit is contained in:
parent
8de3cd7cac
commit
85c904cbf7
@ -1,44 +1,26 @@
|
||||
from apps.common.confirm import *
|
||||
from trezor import ui
|
||||
from trezor.messages import ButtonRequestType
|
||||
from trezor.messages.NEMMosaicDefinition import NEMMosaicDefinition
|
||||
from trezor.messages import NEMMosaicLevy
|
||||
from trezor.ui.text import Text
|
||||
from trezor.ui.scroll import Scrollpage, animate_swipe, paginate
|
||||
from trezor.utils import chunks, format_amount, split_words
|
||||
from .helpers import *
|
||||
|
||||
|
||||
async def require_confirm_action(ctx, action: str):
|
||||
content = Text('Confirm action', ui.ICON_SEND,
|
||||
ui.NORMAL, *split_words(action, 18),
|
||||
icon_color=ui.GREEN)
|
||||
await require_confirm(ctx, content, ButtonRequestType.ConfirmOutput)
|
||||
async def require_confirm_text(ctx, action: str):
|
||||
await require_confirm_content(ctx, 'Confirm action', split_words(action, 18))
|
||||
|
||||
|
||||
async def require_confirm_fee(ctx, action: str, fee: int):
|
||||
content = Text('Confirm fee', ui.ICON_SEND,
|
||||
ui.NORMAL, action,
|
||||
ui.BOLD, format_amount(fee, NEM_MAX_DIVISIBILITY) + ' XEM',
|
||||
icon_color=ui.GREEN)
|
||||
await require_confirm(ctx, content, ButtonRequestType.ConfirmOutput)
|
||||
content = [ui.NORMAL, action,
|
||||
ui.BOLD, format_amount(fee, NEM_MAX_DIVISIBILITY) + ' XEM']
|
||||
await require_confirm_content(ctx, 'Confirm fee', content)
|
||||
|
||||
|
||||
async def require_confirm_transfer(ctx, recipient, value):
|
||||
content = Text('Confirm transfer', ui.ICON_SEND,
|
||||
ui.BOLD, 'Send ' + format_amount(value, NEM_MAX_DIVISIBILITY) + ' XEM',
|
||||
ui.NORMAL, 'to',
|
||||
ui.MONO, *split_address(recipient),
|
||||
icon_color=ui.GREEN)
|
||||
await require_confirm(ctx, content, ButtonRequestType.ConfirmOutput)
|
||||
|
||||
|
||||
async def require_confirm_address(ctx, action: str, address: str):
|
||||
content = Text('Confirm address', ui.ICON_SEND,
|
||||
ui.NORMAL, action,
|
||||
ui.MONO, *split_address(address),
|
||||
icon_color=ui.GREEN)
|
||||
await require_confirm(ctx, content, ButtonRequestType.ConfirmOutput)
|
||||
async def require_confirm_content(ctx, headline: str, content: []):
|
||||
text = Text(headline, ui.ICON_SEND,
|
||||
*content,
|
||||
icon_color=ui.GREEN)
|
||||
await require_confirm(ctx, text, ButtonRequestType.ConfirmOutput)
|
||||
|
||||
|
||||
async def require_confirm_final(ctx, fee: int):
|
||||
@ -50,92 +32,5 @@ async def require_confirm_final(ctx, fee: int):
|
||||
await require_hold_to_confirm(ctx, content, ButtonRequestType.SignTx) # we use SignTx, not ConfirmOutput, for compatibility with T1
|
||||
|
||||
|
||||
async def require_confirm_payload(ctx, payload: bytes, encrypt=False):
|
||||
payload = str(payload, 'utf-8')
|
||||
|
||||
if len(payload) > 48:
|
||||
payload = payload[:48] + '..'
|
||||
if encrypt:
|
||||
content = Text('Confirm payload', ui.ICON_SEND,
|
||||
ui.BOLD, 'Encrypted:',
|
||||
ui.NORMAL, *split_words(payload, 22),
|
||||
icon_color=ui.GREEN)
|
||||
else:
|
||||
content = Text('Confirm payload', ui.ICON_SEND,
|
||||
ui.BOLD, 'Unencrypted:',
|
||||
ui.NORMAL, *split_words(payload, 22),
|
||||
icon_color=ui.RED)
|
||||
await require_confirm(ctx, content, ButtonRequestType.ConfirmOutput)
|
||||
|
||||
|
||||
async def require_confirm_properties(ctx, definition: NEMMosaicDefinition):
|
||||
properties = _get_mosaic_properties(definition)
|
||||
first_page = const(0)
|
||||
paginator = paginate(_show_page, len(properties), first_page, properties)
|
||||
await ctx.wait(paginator)
|
||||
|
||||
|
||||
@ui.layout
|
||||
async def _show_page(page: int, page_count: int, content):
|
||||
content = Scrollpage(content[page], page, page_count)
|
||||
if page + 1 == page_count:
|
||||
await ConfirmDialog(content)
|
||||
else:
|
||||
content.render()
|
||||
await animate_swipe()
|
||||
|
||||
|
||||
def _get_mosaic_properties(definition: NEMMosaicDefinition):
|
||||
properties = []
|
||||
if definition.description:
|
||||
t = Text('Confirm properties', ui.ICON_SEND,
|
||||
ui.BOLD, 'Description:',
|
||||
ui.NORMAL, definition.description)
|
||||
properties.append(t)
|
||||
if definition.transferable:
|
||||
transferable = 'Yes'
|
||||
else:
|
||||
transferable = 'No'
|
||||
t = Text('Confirm properties', ui.ICON_SEND,
|
||||
ui.BOLD, 'Transferable?',
|
||||
ui.NORMAL, transferable)
|
||||
properties.append(t)
|
||||
if definition.mutable_supply:
|
||||
imm = 'mutable'
|
||||
else:
|
||||
imm = 'immutable'
|
||||
if definition.supply:
|
||||
t = Text('Confirm properties', ui.ICON_SEND,
|
||||
ui.BOLD, 'Initial supply:',
|
||||
ui.NORMAL, str(definition.supply),
|
||||
ui.NORMAL, imm)
|
||||
else:
|
||||
t = Text('Confirm properties', ui.ICON_SEND,
|
||||
ui.BOLD, 'Initial supply:',
|
||||
ui.NORMAL, imm)
|
||||
properties.append(t)
|
||||
if definition.levy:
|
||||
t = Text('Confirm properties', ui.ICON_SEND,
|
||||
ui.BOLD, 'Levy recipient:',
|
||||
ui.MONO, *split_address(definition.levy_address))
|
||||
properties.append(t)
|
||||
t = Text('Confirm properties', ui.ICON_SEND,
|
||||
ui.BOLD, 'Levy namespace:',
|
||||
ui.NORMAL, definition.levy_namespace,
|
||||
ui.BOLD, 'Levy mosaic:',
|
||||
ui.NORMAL, definition.levy_mosaic)
|
||||
properties.append(t)
|
||||
if definition.levy == NEMMosaicLevy.MosaicLevy_Absolute:
|
||||
levy_type = 'absolute'
|
||||
else:
|
||||
levy_type = 'percentile'
|
||||
t = Text('Confirm properties', ui.ICON_SEND,
|
||||
ui.BOLD, 'Levy type:',
|
||||
ui.NORMAL, levy_type)
|
||||
properties.append(t)
|
||||
|
||||
return properties
|
||||
|
||||
|
||||
def split_address(data):
|
||||
return chunks(data, 17)
|
||||
|
@ -8,5 +8,5 @@ async def mosaic_creation(ctx, public_key: bytes, msg: NEMSignTx) -> bytearray:
|
||||
|
||||
|
||||
async def supply_change(ctx, public_key: bytes, msg: NEMSignTx):
|
||||
await ask_mosaic_supply_change(ctx, msg)
|
||||
await ask_supply_change(ctx, msg)
|
||||
return serialize_mosaic_supply_change(msg, public_key)
|
||||
|
@ -1,26 +1,110 @@
|
||||
from apps.nem.layout import *
|
||||
from trezor.messages import NEMSignTx
|
||||
from trezor.messages import NEMSupplyChangeType
|
||||
from trezor.messages import NEMMosaicDefinition
|
||||
from trezor.messages import NEMMosaicLevy
|
||||
from trezor.ui.scroll import Scrollpage, animate_swipe, paginate
|
||||
|
||||
|
||||
async def ask_mosaic_creation(ctx, msg: NEMSignTx):
|
||||
await require_confirm_action(ctx, 'Create mosaic "' + msg.mosaic_creation.definition.mosaic + '" under namespace "'
|
||||
+ msg.mosaic_creation.definition.namespace + '"?')
|
||||
await require_confirm_properties(ctx, msg.mosaic_creation.definition)
|
||||
await require_confirm_content(ctx, 'Create mosaic', _creation_message(msg.mosaic_creation))
|
||||
await _require_confirm_properties(ctx, msg.mosaic_creation.definition)
|
||||
await require_confirm_fee(ctx, 'Confirm creation fee', msg.mosaic_creation.fee)
|
||||
|
||||
await require_confirm_final(ctx, msg.transaction.fee)
|
||||
|
||||
|
||||
async def ask_mosaic_supply_change(ctx, msg: NEMSignTx):
|
||||
await require_confirm_action(ctx, 'Modify supply for "' + msg.supply_change.mosaic + '" under namespace "'
|
||||
+ msg.supply_change.namespace + '"?')
|
||||
async def ask_supply_change(ctx, msg: NEMSignTx):
|
||||
await require_confirm_content(ctx, 'Supply change', _supply_message(msg.supply_change))
|
||||
if msg.supply_change.type == NEMSupplyChangeType.SupplyChange_Decrease:
|
||||
ask_msg = 'Decrease supply by ' + str(msg.supply_change.delta) + ' whole units?'
|
||||
elif msg.supply_change.type == NEMSupplyChangeType.SupplyChange_Increase:
|
||||
ask_msg = 'Increase supply by ' + str(msg.supply_change.delta) + ' whole units?'
|
||||
else:
|
||||
raise ValueError('Invalid supply change type')
|
||||
await require_confirm_action(ctx, ask_msg)
|
||||
await require_confirm_text(ctx, ask_msg)
|
||||
|
||||
await require_confirm_final(ctx, msg.transaction.fee)
|
||||
|
||||
|
||||
def _creation_message(mosaic_creation):
|
||||
return [ui.NORMAL, 'Create mosaic',
|
||||
ui.BOLD, mosaic_creation.definition.mosaic,
|
||||
ui.NORMAL, 'under namespace',
|
||||
ui.BOLD, mosaic_creation.definition.namespace]
|
||||
|
||||
|
||||
def _supply_message(supply_change):
|
||||
return [ui.NORMAL, 'Modify supply for',
|
||||
ui.BOLD, supply_change.mosaic,
|
||||
ui.NORMAL, 'under namespace',
|
||||
ui.BOLD, supply_change.namespace]
|
||||
|
||||
|
||||
async def _require_confirm_properties(ctx, definition: NEMMosaicDefinition):
|
||||
properties = _get_mosaic_properties(definition)
|
||||
first_page = const(0)
|
||||
paginator = paginate(_show_page, len(properties), first_page, properties)
|
||||
await ctx.wait(paginator)
|
||||
|
||||
|
||||
@ui.layout
|
||||
async def _show_page(page: int, page_count: int, content):
|
||||
content = Scrollpage(content[page], page, page_count)
|
||||
if page + 1 == page_count:
|
||||
await ConfirmDialog(content)
|
||||
else:
|
||||
content.render()
|
||||
await animate_swipe()
|
||||
|
||||
|
||||
def _get_mosaic_properties(definition: NEMMosaicDefinition):
|
||||
properties = []
|
||||
if definition.description:
|
||||
t = Text('Confirm properties', ui.ICON_SEND,
|
||||
ui.BOLD, 'Description:',
|
||||
ui.NORMAL, definition.description)
|
||||
properties.append(t)
|
||||
if definition.transferable:
|
||||
transferable = 'Yes'
|
||||
else:
|
||||
transferable = 'No'
|
||||
t = Text('Confirm properties', ui.ICON_SEND,
|
||||
ui.BOLD, 'Transferable?',
|
||||
ui.NORMAL, transferable)
|
||||
properties.append(t)
|
||||
if definition.mutable_supply:
|
||||
imm = 'mutable'
|
||||
else:
|
||||
imm = 'immutable'
|
||||
if definition.supply:
|
||||
t = Text('Confirm properties', ui.ICON_SEND,
|
||||
ui.BOLD, 'Initial supply:',
|
||||
ui.NORMAL, str(definition.supply),
|
||||
ui.NORMAL, imm)
|
||||
else:
|
||||
t = Text('Confirm properties', ui.ICON_SEND,
|
||||
ui.BOLD, 'Initial supply:',
|
||||
ui.NORMAL, imm)
|
||||
properties.append(t)
|
||||
if definition.levy:
|
||||
t = Text('Confirm properties', ui.ICON_SEND,
|
||||
ui.BOLD, 'Levy recipient:',
|
||||
ui.MONO, *split_address(definition.levy_address))
|
||||
properties.append(t)
|
||||
t = Text('Confirm properties', ui.ICON_SEND,
|
||||
ui.BOLD, 'Levy namespace:',
|
||||
ui.NORMAL, definition.levy_namespace,
|
||||
ui.BOLD, 'Levy mosaic:',
|
||||
ui.NORMAL, definition.levy_mosaic)
|
||||
properties.append(t)
|
||||
if definition.levy == NEMMosaicLevy.MosaicLevy_Absolute:
|
||||
levy_type = 'absolute'
|
||||
else:
|
||||
levy_type = 'percentile'
|
||||
t = Text('Confirm properties', ui.ICON_SEND,
|
||||
ui.BOLD, 'Levy type:',
|
||||
ui.NORMAL, levy_type)
|
||||
properties.append(t)
|
||||
|
||||
return properties
|
||||
|
@ -7,15 +7,15 @@ from trezor.crypto import nem
|
||||
async def ask_multisig(ctx, msg: NEMSignTx):
|
||||
address = nem.compute_address(msg.multisig.signer, msg.transaction.network)
|
||||
if msg.cosigning:
|
||||
await require_confirm_address(ctx, 'Cosign transaction for', address)
|
||||
await _require_confirm_address(ctx, 'Cosign transaction for', address)
|
||||
else:
|
||||
await require_confirm_address(ctx, 'Initiate transaction for', address)
|
||||
await _require_confirm_address(ctx, 'Initiate transaction for', address)
|
||||
await require_confirm_fee(ctx, 'Confirm multisig fee', msg.multisig.fee)
|
||||
|
||||
|
||||
async def ask_aggregate_modification(ctx, msg: NEMSignTx):
|
||||
if not msg.multisig:
|
||||
await require_confirm_action(ctx, 'Convert account to multisig account?')
|
||||
await require_confirm_text(ctx, 'Convert account to multisig account?')
|
||||
|
||||
for m in msg.aggregate_modification.modifications:
|
||||
if m.type == NEMModificationType.CosignatoryModification_Add:
|
||||
@ -23,14 +23,21 @@ async def ask_aggregate_modification(ctx, msg: NEMSignTx):
|
||||
else:
|
||||
action = 'Remove'
|
||||
address = nem.compute_address(m.public_key, msg.transaction.network)
|
||||
await require_confirm_address(ctx, action + ' cosignatory?', address)
|
||||
await _require_confirm_address(ctx, action + ' cosignatory', address)
|
||||
|
||||
if msg.aggregate_modification.relative_change:
|
||||
if not msg.multisig:
|
||||
action = 'Set minimum cosignatories to '
|
||||
else:
|
||||
action = 'Modify the number of cosignatories by '
|
||||
await require_confirm_action(ctx, action + str(msg.aggregate_modification.relative_change) + '?')
|
||||
await require_confirm_text(ctx, action + str(msg.aggregate_modification.relative_change) + '?')
|
||||
|
||||
await require_confirm_final(ctx, msg.transaction.fee)
|
||||
|
||||
|
||||
async def _require_confirm_address(ctx, action: str, address: str):
|
||||
content = Text('Confirm address', ui.ICON_SEND,
|
||||
ui.NORMAL, action,
|
||||
ui.MONO, *split_address(address),
|
||||
icon_color=ui.GREEN)
|
||||
await require_confirm(ctx, content, ButtonRequestType.ConfirmOutput)
|
||||
|
@ -4,10 +4,16 @@ from trezor.messages import NEMSignTx
|
||||
|
||||
async def ask_provision_namespace(ctx, msg: NEMSignTx):
|
||||
if msg.provision_namespace.parent:
|
||||
await require_confirm_action(ctx, 'Create namespace "' + msg.provision_namespace.namespace + '"' +
|
||||
'under namespace "' + msg.provision_namespace.parent + '"?')
|
||||
content = [ui.NORMAL, 'Create namespace',
|
||||
ui.BOLD, msg.provision_namespace.namespace,
|
||||
ui.NORMAL, 'under namespace',
|
||||
ui.BOLD, msg.provision_namespace.parent]
|
||||
await require_confirm_content(ctx, 'Confirm namespace', content)
|
||||
else:
|
||||
await require_confirm_action(ctx, 'Create namespace "' + msg.provision_namespace.namespace + '"?')
|
||||
content = [ui.NORMAL, 'Create namespace',
|
||||
ui.BOLD, msg.provision_namespace.namespace]
|
||||
await require_confirm_content(ctx, 'Confirm namespace', content)
|
||||
|
||||
await require_confirm_fee(ctx, 'Confirm rental fee', msg.provision_namespace.fee)
|
||||
|
||||
await require_confirm_final(ctx, msg.transaction.fee)
|
||||
|
@ -5,13 +5,12 @@ from trezor.messages import NEMSignTx
|
||||
|
||||
async def ask_transfer(ctx, msg: NEMSignTx, payload, encrypted):
|
||||
if payload:
|
||||
await require_confirm_payload(ctx, msg.transfer.payload, encrypted)
|
||||
await _require_confirm_payload(ctx, msg.transfer.payload, encrypted)
|
||||
|
||||
for mosaic in msg.transfer.mosaics:
|
||||
await require_confirm_action(ctx, 'Confirm transfer of ' + str(mosaic.quantity) +
|
||||
' raw units of ' + mosaic.namespace + '.' + mosaic.mosaic)
|
||||
await require_confirm_content(ctx, 'Confirm mosaic', _mosaics_message(mosaic))
|
||||
|
||||
await require_confirm_transfer(ctx, msg.transfer.recipient, msg.transfer.amount)
|
||||
await _require_confirm_transfer(ctx, msg.transfer.recipient, msg.transfer.amount)
|
||||
|
||||
await require_confirm_final(ctx, msg.transaction.fee)
|
||||
|
||||
@ -21,5 +20,39 @@ async def ask_importance_transfer(ctx, msg: NEMSignTx):
|
||||
m = 'Activate'
|
||||
else:
|
||||
m = 'Deactivate'
|
||||
await require_confirm_action(ctx, m + ' remote harvesting?')
|
||||
await require_confirm_text(ctx, m + ' remote harvesting?')
|
||||
await require_confirm_final(ctx, msg.transaction.fee)
|
||||
|
||||
|
||||
async def _require_confirm_transfer(ctx, recipient, value):
|
||||
content = Text('Confirm transfer', ui.ICON_SEND,
|
||||
ui.BOLD, 'Send ' + format_amount(value, NEM_MAX_DIVISIBILITY) + ' XEM',
|
||||
ui.NORMAL, 'to',
|
||||
ui.MONO, *split_address(recipient),
|
||||
icon_color=ui.GREEN)
|
||||
await require_confirm(ctx, content, ButtonRequestType.ConfirmOutput)
|
||||
|
||||
|
||||
async def _require_confirm_payload(ctx, payload: bytes, encrypt=False):
|
||||
payload = str(payload, 'utf-8')
|
||||
|
||||
if len(payload) > 48:
|
||||
payload = payload[:48] + '..'
|
||||
if encrypt:
|
||||
content = Text('Confirm payload', ui.ICON_SEND,
|
||||
ui.BOLD, 'Encrypted:',
|
||||
ui.NORMAL, *split_words(payload, 22),
|
||||
icon_color=ui.GREEN)
|
||||
else:
|
||||
content = Text('Confirm payload', ui.ICON_SEND,
|
||||
ui.BOLD, 'Unencrypted:',
|
||||
ui.NORMAL, *split_words(payload, 22),
|
||||
icon_color=ui.RED)
|
||||
await require_confirm(ctx, content, ButtonRequestType.ConfirmOutput)
|
||||
|
||||
|
||||
def _mosaics_message(mosaic):
|
||||
return [ui.NORMAL, 'Confirm transfer of',
|
||||
ui.BOLD, str(mosaic.quantity) + ' raw units',
|
||||
ui.NORMAL, 'of',
|
||||
ui.BOLD, mosaic.namespace + '.' + mosaic.mosaic]
|
||||
|
Loading…
Reference in New Issue
Block a user