1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-12-17 03:48:09 +00:00

nem: layout refactoring and fixes

This commit is contained in:
Tomas Susanka 2018-04-12 14:59:31 +02:00 committed by Jan Pochyla
parent 8de3cd7cac
commit 85c904cbf7
6 changed files with 161 additions and 136 deletions

View File

@ -1,44 +1,26 @@
from apps.common.confirm import * from apps.common.confirm import *
from trezor import ui from trezor import ui
from trezor.messages import ButtonRequestType 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.text import Text
from trezor.ui.scroll import Scrollpage, animate_swipe, paginate
from trezor.utils import chunks, format_amount, split_words from trezor.utils import chunks, format_amount, split_words
from .helpers import * from .helpers import *
async def require_confirm_action(ctx, action: str): async def require_confirm_text(ctx, action: str):
content = Text('Confirm action', ui.ICON_SEND, await require_confirm_content(ctx, 'Confirm action', split_words(action, 18))
ui.NORMAL, *split_words(action, 18),
icon_color=ui.GREEN)
await require_confirm(ctx, content, ButtonRequestType.ConfirmOutput)
async def require_confirm_fee(ctx, action: str, fee: int): async def require_confirm_fee(ctx, action: str, fee: int):
content = Text('Confirm fee', ui.ICON_SEND, content = [ui.NORMAL, action,
ui.NORMAL, action, ui.BOLD, format_amount(fee, NEM_MAX_DIVISIBILITY) + ' XEM']
ui.BOLD, format_amount(fee, NEM_MAX_DIVISIBILITY) + ' XEM', await require_confirm_content(ctx, 'Confirm fee', content)
icon_color=ui.GREEN)
await require_confirm(ctx, content, ButtonRequestType.ConfirmOutput)
async def require_confirm_transfer(ctx, recipient, value): async def require_confirm_content(ctx, headline: str, content: []):
content = Text('Confirm transfer', ui.ICON_SEND, text = Text(headline, ui.ICON_SEND,
ui.BOLD, 'Send ' + format_amount(value, NEM_MAX_DIVISIBILITY) + ' XEM', *content,
ui.NORMAL, 'to', icon_color=ui.GREEN)
ui.MONO, *split_address(recipient), await require_confirm(ctx, text, ButtonRequestType.ConfirmOutput)
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_final(ctx, fee: int): 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 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): def split_address(data):
return chunks(data, 17) return chunks(data, 17)

View File

@ -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): 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) return serialize_mosaic_supply_change(msg, public_key)

View File

@ -1,26 +1,110 @@
from apps.nem.layout import * from apps.nem.layout import *
from trezor.messages import NEMSignTx from trezor.messages import NEMSignTx
from trezor.messages import NEMSupplyChangeType 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): async def ask_mosaic_creation(ctx, msg: NEMSignTx):
await require_confirm_action(ctx, 'Create mosaic "' + msg.mosaic_creation.definition.mosaic + '" under namespace "' await require_confirm_content(ctx, 'Create mosaic', _creation_message(msg.mosaic_creation))
+ msg.mosaic_creation.definition.namespace + '"?') await _require_confirm_properties(ctx, msg.mosaic_creation.definition)
await require_confirm_properties(ctx, msg.mosaic_creation.definition)
await require_confirm_fee(ctx, 'Confirm creation fee', msg.mosaic_creation.fee) await require_confirm_fee(ctx, 'Confirm creation fee', msg.mosaic_creation.fee)
await require_confirm_final(ctx, msg.transaction.fee) await require_confirm_final(ctx, msg.transaction.fee)
async def ask_mosaic_supply_change(ctx, msg: NEMSignTx): async def ask_supply_change(ctx, msg: NEMSignTx):
await require_confirm_action(ctx, 'Modify supply for "' + msg.supply_change.mosaic + '" under namespace "' await require_confirm_content(ctx, 'Supply change', _supply_message(msg.supply_change))
+ msg.supply_change.namespace + '"?')
if msg.supply_change.type == NEMSupplyChangeType.SupplyChange_Decrease: if msg.supply_change.type == NEMSupplyChangeType.SupplyChange_Decrease:
ask_msg = 'Decrease supply by ' + str(msg.supply_change.delta) + ' whole units?' ask_msg = 'Decrease supply by ' + str(msg.supply_change.delta) + ' whole units?'
elif msg.supply_change.type == NEMSupplyChangeType.SupplyChange_Increase: elif msg.supply_change.type == NEMSupplyChangeType.SupplyChange_Increase:
ask_msg = 'Increase supply by ' + str(msg.supply_change.delta) + ' whole units?' ask_msg = 'Increase supply by ' + str(msg.supply_change.delta) + ' whole units?'
else: else:
raise ValueError('Invalid supply change type') 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) 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

View File

@ -7,15 +7,15 @@ from trezor.crypto import nem
async def ask_multisig(ctx, msg: NEMSignTx): async def ask_multisig(ctx, msg: NEMSignTx):
address = nem.compute_address(msg.multisig.signer, msg.transaction.network) address = nem.compute_address(msg.multisig.signer, msg.transaction.network)
if msg.cosigning: if msg.cosigning:
await require_confirm_address(ctx, 'Cosign transaction for', address) await _require_confirm_address(ctx, 'Cosign transaction for', address)
else: 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) await require_confirm_fee(ctx, 'Confirm multisig fee', msg.multisig.fee)
async def ask_aggregate_modification(ctx, msg: NEMSignTx): async def ask_aggregate_modification(ctx, msg: NEMSignTx):
if not msg.multisig: 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: for m in msg.aggregate_modification.modifications:
if m.type == NEMModificationType.CosignatoryModification_Add: if m.type == NEMModificationType.CosignatoryModification_Add:
@ -23,14 +23,21 @@ async def ask_aggregate_modification(ctx, msg: NEMSignTx):
else: else:
action = 'Remove' action = 'Remove'
address = nem.compute_address(m.public_key, msg.transaction.network) 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 msg.aggregate_modification.relative_change:
if not msg.multisig: if not msg.multisig:
action = 'Set minimum cosignatories to ' action = 'Set minimum cosignatories to '
else: else:
action = 'Modify the number of cosignatories by ' 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) 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)

View File

@ -4,10 +4,16 @@ from trezor.messages import NEMSignTx
async def ask_provision_namespace(ctx, msg: NEMSignTx): async def ask_provision_namespace(ctx, msg: NEMSignTx):
if msg.provision_namespace.parent: if msg.provision_namespace.parent:
await require_confirm_action(ctx, 'Create namespace "' + msg.provision_namespace.namespace + '"' + content = [ui.NORMAL, 'Create namespace',
'under namespace "' + msg.provision_namespace.parent + '"?') 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: 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_fee(ctx, 'Confirm rental fee', msg.provision_namespace.fee)
await require_confirm_final(ctx, msg.transaction.fee) await require_confirm_final(ctx, msg.transaction.fee)

View File

@ -5,13 +5,12 @@ from trezor.messages import NEMSignTx
async def ask_transfer(ctx, msg: NEMSignTx, payload, encrypted): async def ask_transfer(ctx, msg: NEMSignTx, payload, encrypted):
if payload: 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: for mosaic in msg.transfer.mosaics:
await require_confirm_action(ctx, 'Confirm transfer of ' + str(mosaic.quantity) + await require_confirm_content(ctx, 'Confirm mosaic', _mosaics_message(mosaic))
' raw units of ' + mosaic.namespace + '.' + mosaic.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) await require_confirm_final(ctx, msg.transaction.fee)
@ -21,5 +20,39 @@ async def ask_importance_transfer(ctx, msg: NEMSignTx):
m = 'Activate' m = 'Activate'
else: else:
m = 'Deactivate' 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) 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]