apps: use mutable Text API

pull/25/head
Jan Pochyla 6 years ago
parent 49e75851c7
commit b3d3da7f7a

@ -10,10 +10,11 @@ from trezor.utils import chunks
async def show_address(ctx, address: str):
lines = split_address(address)
content = Text('Confirm address', ui.ICON_RECEIVE, ui.MONO, *lines, icon_color=ui.GREEN)
text = Text('Confirm address', ui.ICON_RECEIVE, icon_color=ui.GREEN)
text.mono(*lines)
return await confirm(
ctx,
content,
text,
code=ButtonRequestType.Address,
cancel='QR',
cancel_style=ui.BTN_KEY)
@ -24,9 +25,9 @@ async def show_qr(ctx, address: str):
qr_y = const(115)
qr_coef = const(4)
content = Container(
Qr(address, (qr_x, qr_y), qr_coef),
Text('Confirm address', ui.ICON_RECEIVE, ui.MONO, icon_color=ui.GREEN))
qr = Qr(address, (qr_x, qr_y), qr_coef)
text = Text('Confirm address', ui.ICON_RECEIVE, icon_color=ui.GREEN)
content = Container(qr, text)
return await confirm(
ctx,
content,

@ -13,9 +13,8 @@ from apps.common.cache import get_state
@ui.layout
async def request_passphrase_entry(ctx):
text = Text(
'Enter passphrase', ui.ICON_CONFIG,
'Where to enter your', 'passphrase?')
text = Text('Enter passphrase', ui.ICON_CONFIG)
text.type('Where to enter your', 'passphrase?')
text.render()
ack = await ctx.call(
@ -32,9 +31,8 @@ async def request_passphrase_entry(ctx):
@ui.layout
async def request_passphrase_ack(ctx, on_device):
if not on_device:
text = Text(
'Passphrase entry', ui.ICON_CONFIG,
'Please, type passphrase', 'on connected host.')
text = Text('Passphrase entry', ui.ICON_CONFIG)
text.type('Please, type passphrase', 'on connected host.')
text.render()
req = PassphraseRequest(on_device=on_device)

@ -12,26 +12,25 @@ from apps.ethereum.get_address import _ethereum_address_hex
async def require_confirm_tx(ctx, to, value, chain_id, token=None, tx_type=None):
if to:
str_to = _ethereum_address_hex(to, networks.by_chain_id(chain_id))
to_str = _ethereum_address_hex(to, networks.by_chain_id(chain_id))
else:
str_to = 'new contract?'
content = Text('Confirm sending', ui.ICON_SEND,
ui.BOLD, format_ethereum_amount(value, token, chain_id, tx_type),
ui.NORMAL, 'to',
ui.MONO, *split_address(str_to),
icon_color=ui.GREEN)
await require_confirm(ctx, content, ButtonRequestType.SignTx) # we use SignTx, not ConfirmOutput, for compatibility with T1
to_str = 'new contract?'
text = Text('Confirm sending', ui.ICON_SEND, icon_color=ui.GREEN)
text.bold(format_ethereum_amount(value, token, chain_id, tx_type))
text.type('to')
text.mono(*split_address(to_str))
# we use SignTx, not ConfirmOutput, for compatibility with T1
await require_confirm(ctx, text, ButtonRequestType.SignTx)
async def require_confirm_fee(ctx, spending, gas_price, gas_limit, chain_id, token=None, tx_type=None):
content = Text('Confirm transaction', ui.ICON_SEND,
ui.BOLD, format_ethereum_amount(spending, token, chain_id, tx_type),
ui.NORMAL, 'Gas price:',
ui.BOLD, format_ethereum_amount(gas_price, None, chain_id, tx_type),
ui.NORMAL, 'Maximum fee:',
ui.BOLD, format_ethereum_amount(gas_price * gas_limit, None, chain_id, tx_type),
icon_color=ui.GREEN)
await require_hold_to_confirm(ctx, content, ButtonRequestType.SignTx)
text = Text('Confirm transaction', ui.ICON_SEND, icon_color=ui.GREEN)
text.bold(format_ethereum_amount(spending, token, chain_id, tx_type))
text.type('Gas price:')
text.bold(format_ethereum_amount(gas_price, None, chain_id, tx_type))
text.type('Maximum fee:')
text.bold(format_ethereum_amount(gas_price * gas_limit, None, chain_id, tx_type))
await require_hold_to_confirm(ctx, text, ButtonRequestType.SignTx)
def split_data(data):
@ -39,14 +38,14 @@ def split_data(data):
async def require_confirm_data(ctx, data, data_total):
str_data = hexlify(data[:36]).decode()
data_str = hexlify(data[:36]).decode()
if data_total > 36:
str_data = str_data[:-2] + '..'
content = Text('Confirm data', ui.ICON_SEND,
ui.BOLD, 'Size: %d bytes' % data_total,
ui.MONO, *split_data(str_data),
icon_color=ui.GREEN)
await require_confirm(ctx, content, ButtonRequestType.SignTx) # we use SignTx, not ConfirmOutput, for compatibility with T1
data_str = data_str[:-2] + '..'
text = Text('Confirm data', ui.ICON_SEND, icon_color=ui.GREEN)
text.bold('Size: %d bytes' % data_total)
text.mono(*split_data(data_str))
# we use SignTx, not ConfirmOutput, for compatibility with T1
await require_confirm(ctx, text, ButtonRequestType.SignTx)
def split_address(address):

@ -37,5 +37,6 @@ async def ethereum_sign_message(ctx, msg):
async def require_confirm_sign_message(ctx, message):
message = split_message(message)
content = Text('Sign ETH message', ui.ICON_DEFAULT, max_lines=5, *message)
await require_confirm(ctx, content)
text = Text('Sign ETH message', ui.ICON_DEFAULT)
text.type(*message)
await require_confirm(ctx, text)

@ -32,10 +32,10 @@ async def ethereum_verify_message(ctx, msg):
async def require_confirm_verify_message(ctx, address, message):
lines = split_address(address)
content = Text('Confirm address', ui.ICON_DEFAULT, ui.MONO, *lines)
await require_confirm(ctx, content)
text = Text('Confirm address', ui.ICON_DEFAULT)
text.mono(*split_address(address))
await require_confirm(ctx, text)
message = split_message(message)
content = Text('Verify message', ui.ICON_DEFAULT, max_lines=5, *message)
await require_confirm(ctx, content)
text = Text('Verify message', ui.ICON_DEFAULT)
text.mono(*split_message(message))
await require_confirm(ctx, text)

@ -391,12 +391,8 @@ class ConfirmState:
from trezor.ui.text import Text
if bytes(self.app_id) == _BOGUS_APPID:
text = Text(
'U2F mismatch', ui.ICON_WRONG,
'Another U2F device',
'was used to register',
'in this application.',
icon_color=ui.RED)
text = Text('U2F mismatch', ui.ICON_WRONG, icon_color=ui.RED)
text.type('Another U2F device', 'was used to register', 'in this application.')
text.render()
await loop.sleep(3 * 1000 * 1000)
self.confirmed = True

@ -9,28 +9,25 @@ from .helpers import get_vote_tx_text
async def require_confirm_tx(ctx, to, value):
content = Text('Confirm sending', ui.ICON_SEND,
ui.BOLD, format_amount(value),
ui.NORMAL, 'to',
ui.MONO, *split_address(to),
icon_color=ui.GREEN)
return await require_confirm(ctx, content, ButtonRequestType.SignTx)
text = Text('Confirm sending', ui.ICON_SEND, icon_color=ui.GREEN)
text.bold(format_amount(value))
text.type('to')
text.mono(*split_address(to))
return await require_confirm(ctx, text, ButtonRequestType.SignTx)
async def require_confirm_delegate_registration(ctx, delegate_name):
content = Text('Confirm transaction', ui.ICON_SEND,
'Do you really want to',
'register a delegate?',
ui.BOLD, *chunks(delegate_name, 20),
icon_color=ui.GREEN)
return await require_confirm(ctx, content, ButtonRequestType.SignTx)
text = Text('Confirm transaction', ui.ICON_SEND, icon_color=ui.GREEN)
text.type('Do you really want to')
text.type('register a delegate?')
text.bold(*chunks(delegate_name, 20))
return await require_confirm(ctx, text, ButtonRequestType.SignTx)
async def require_confirm_vote_tx(ctx, votes):
content = Text('Confirm transaction', ui.ICON_SEND,
*get_vote_tx_text(votes),
icon_color=ui.GREEN)
return await require_confirm(ctx, content, ButtonRequestType.SignTx)
text = Text('Confirm transaction', ui.ICON_SEND, icon_color=ui.GREEN)
text.type(*get_vote_tx_text(votes))
return await require_confirm(ctx, text, ButtonRequestType.SignTx)
async def require_confirm_public_key(ctx, public_key):
@ -38,21 +35,19 @@ async def require_confirm_public_key(ctx, public_key):
async def require_confirm_multisig(ctx, multisignature):
content = Text('Confirm transaction', ui.ICON_SEND,
('Keys group length: %s' % len(multisignature.keys_group)),
('Life time: %s' % multisignature.life_time),
('Min: %s' % multisignature.min),
icon_color=ui.GREEN)
return await require_confirm(ctx, content, ButtonRequestType.SignTx)
text = Text('Confirm transaction', ui.ICON_SEND, icon_color=ui.GREEN)
text.type('Keys group length: %s' % len(multisignature.keys_group))
text.type('Life time: %s' % multisignature.life_time)
text.type('Min: %s' % multisignature.min)
return await require_confirm(ctx, text, ButtonRequestType.SignTx)
async def require_confirm_fee(ctx, value, fee):
content = Text('Confirm transaction', ui.ICON_SEND,
ui.BOLD, format_amount(value),
ui.NORMAL, 'fee:',
ui.BOLD, format_amount(fee),
icon_color=ui.GREEN)
await require_hold_to_confirm(ctx, content, ButtonRequestType.ConfirmOutput)
text = Text('Confirm transaction', ui.ICON_SEND, icon_color=ui.GREEN)
text.bold(format_amount(value))
text.type('fee:')
text.bold(format_amount(fee))
await require_hold_to_confirm(ctx, text, ButtonRequestType.ConfirmOutput)
def format_amount(value):

@ -39,6 +39,6 @@ async def lisk_sign_message(ctx, msg):
async def require_confirm_sign_message(ctx, message):
message = split_message(message)
content = Text('Sign Lisk message', ui.ICON_DEFAULT, max_lines=5, *message)
await require_confirm(ctx, content)
text = Text('Sign Lisk message', ui.ICON_DEFAULT)
text.type(*split_message(message))
await require_confirm(ctx, text)

@ -13,40 +13,16 @@ async def apply_settings(ctx, msg):
if msg.homescreen is not None:
if len(msg.homescreen) > storage.HOMESCREEN_MAXSIZE:
raise wire.DataError('Homescreen is too complex')
await require_confirm(ctx, Text(
'Change homescreen', ui.ICON_CONFIG,
'Do you really want to', 'change homescreen?'),
code=ButtonRequestType.ProtectCall)
await require_confirm_change_homescreen(ctx)
# TODO: split label (bold) and '?' (normal) once we support mixed styles on one line
if msg.label is not None:
await require_confirm(ctx, Text(
'Change label', ui.ICON_CONFIG,
'Do you really want to', 'change label to',
ui.BOLD, '%s?' % msg.label),
code=ButtonRequestType.ProtectCall)
await require_confirm_change_label(ctx, msg.label)
if msg.use_passphrase is not None:
await require_confirm(ctx, Text(
'Enable passphrase' if msg.use_passphrase else 'Disable passphrase',
ui.ICON_CONFIG,
'Do you really want to',
'enable passphrase' if msg.use_passphrase else 'disable passphrase',
'encryption?'),
code=ButtonRequestType.ProtectCall)
await require_confirm_change_passphrase(ctx, msg.use_passphrase)
if msg.passphrase_source is not None:
if msg.passphrase_source == PassphraseSourceType.DEVICE:
desc = 'ON DEVICE'
elif msg.passphrase_source == PassphraseSourceType.HOST:
desc = 'ON HOST'
else:
desc = 'ASK'
await require_confirm(ctx, Text(
'Passphrase source', ui.ICON_CONFIG,
'Do you really want to', 'change the passphrase', 'source to',
ui.BOLD, 'ALWAYS %s?' % desc),
code=ButtonRequestType.ProtectCall)
await require_confirm_change_passphrase_source(ctx, msg.passphrase_source)
storage.load_settings(label=msg.label,
use_passphrase=msg.use_passphrase,
@ -54,3 +30,37 @@ async def apply_settings(ctx, msg):
passphrase_source=msg.passphrase_source)
return Success(message='Settings applied')
async def require_confirm_change_homescreen(ctx):
text = Text('Change homescreen', ui.ICON_CONFIG)
text.type('Do you really want to', 'change homescreen?')
await require_confirm(ctx, text, code=ButtonRequestType.ProtectCall)
async def require_confirm_change_label(ctx, label):
text = Text('Change label', ui.ICON_CONFIG)
text.type('Do you really want to', 'change label to')
text.bold('%s?' % label)
await require_confirm(ctx, text, code=ButtonRequestType.ProtectCall)
async def require_confirm_change_passphrase(ctx, use):
text = Text('Enable passphrase' if use else 'Disable passphrase', ui.ICON_CONFIG)
text.type('Do you really want to')
text.type('enable passphrase' if use else 'disable passphrase')
text.type('encryption?')
await require_confirm(ctx, text, code=ButtonRequestType.ProtectCall)
async def require_confirm_change_passphrase_source(ctx, source):
if source == PassphraseSourceType.DEVICE:
desc = 'ON DEVICE'
elif source == PassphraseSourceType.HOST:
desc = 'ON HOST'
else:
desc = 'ASK'
text = Text('Passphrase source', ui.ICON_CONFIG)
text.type('Do you really want to', 'change the passphrase', 'source to')
text.bold('ALWAYS %s?' % desc)
await require_confirm(ctx, text, code=ButtonRequestType.ProtectCall)

@ -42,22 +42,22 @@ def require_confirm_change_pin(ctx, msg):
has_pin = config.has_pin()
if msg.remove and has_pin: # removing pin
return require_confirm(ctx, Text(
'Remove PIN', ui.ICON_CONFIG,
'Do you really want to', ui.BOLD,
'remove current PIN?'))
text = Text('Remove PIN', ui.ICON_CONFIG)
text.type('Do you really want to')
text.bold('remove current PIN?')
return require_confirm(ctx, text)
if not msg.remove and has_pin: # changing pin
return require_confirm(ctx, Text(
'Change PIN', ui.ICON_CONFIG,
'Do you really want to', ui.BOLD,
'change current PIN?'))
text = Text('Remove PIN', ui.ICON_CONFIG)
text.type('Do you really want to')
text.bold('change current PIN?')
return require_confirm(ctx, text)
if not msg.remove and not has_pin: # setting new pin
return require_confirm(ctx, Text(
'Change PIN', ui.ICON_CONFIG,
'Do you really want to', ui.BOLD,
'set new PIN?'))
text = Text('Remove PIN', ui.ICON_CONFIG)
text.type('Do you really want to')
text.bold('set new PIN?')
return require_confirm(ctx, text)
async def request_pin_confirm(ctx, *args, **kwargs):
@ -79,11 +79,9 @@ async def request_pin_ack(ctx, *args, **kwargs):
@ui.layout
async def pin_mismatch():
text = Text(
'PIN mismatch', ui.ICON_WRONG,
'Entered PINs do not',
'match each other.',
'',
'Please, try again...', icon_color=ui.RED)
text = Text('PIN mismatch', ui.ICON_WRONG, icon_color=ui.RED)
text.type('Entered PINs do not', 'match each other.')
text.type('')
text.type('Please, try again...')
text.render()
await loop.sleep(3 * 1000 * 1000)

@ -18,10 +18,10 @@ async def load_device(ctx, msg):
if not msg.skip_checksum and not bip39.check(msg.mnemonic):
raise wire.ProcessError('Mnemonic is not valid')
await require_confirm(ctx, Text(
'Loading seed', ui.ICON_DEFAULT,
ui.BOLD, 'Loading private seed', 'is not recommended.',
ui.NORMAL, 'Continue only if you', 'know what you are doing!'))
text = Text('Loading seed', ui.ICON_DEFAULT)
text.bold('Loading private seed', 'is not recommended.')
text.type('Continue only if you', 'know what you are doing!')
await require_confirm(ctx, text)
storage.load_mnemonic(
mnemonic=msg.mnemonic, needs_backup=True)

@ -61,9 +61,9 @@ async def recovery_device(ctx, msg):
async def request_wordcount(ctx):
await ctx.call(ButtonRequest(code=MnemonicWordCount), ButtonAck)
content = Text('Device recovery', ui.ICON_RECOVERY, 'Number of words?')
select = WordSelector(content)
count = await ctx.wait(select)
text = Text('Device recovery', ui.ICON_RECOVERY)
text.type('Number of words?')
count = await ctx.wait(WordSelector(text))
return count

@ -88,56 +88,57 @@ def generate_mnemonic(strength: int,
async def show_warning(ctx):
content = Text(
'Backup your seed', ui.ICON_NOCOPY,
text = Text('Backup your seed', ui.ICON_NOCOPY)
text.type(
'Never make a digital',
'copy of your recovery',
'seed and never upload',
'it online!')
await require_confirm(
ctx,
content,
text,
ButtonRequestType.ResetDevice,
confirm='I understand',
cancel=None)
async def show_wrong_entry(ctx):
content = Text(
'Wrong entry!', ui.ICON_WRONG,
text = Text('Wrong entry!', ui.ICON_WRONG, icon_color=ui.RED)
text.type(
'You have entered',
'wrong seed word.',
'Please check again.', icon_color=ui.RED)
'Please check again.')
await require_confirm(
ctx,
content,
text,
ButtonRequestType.ResetDevice,
confirm='Check again',
cancel=None)
async def show_success(ctx):
content = Text(
'Backup is done!', ui.ICON_CONFIRM,
text = Text('Backup is done!', ui.ICON_CONFIRM, icon_color=ui.GREEN)
text.type(
'Never make a digital',
'copy of your recovery',
'seed and never upload',
'it online!', icon_color=ui.GREEN)
'it online!')
await require_confirm(
ctx,
content,
text,
ButtonRequestType.ResetDevice,
confirm='Finish setup',
cancel=None)
async def show_entropy(ctx, entropy: bytes):
estr = hexlify(entropy).decode()
lines = chunks(estr, 16)
content = Text('Internal entropy', ui.ICON_RESET, ui.MONO, *lines)
entropy_str = hexlify(entropy).decode()
lines = chunks(entropy_str, 16)
text = Text('Internal entropy', ui.ICON_RESET)
text.mono(*lines)
await require_confirm(
ctx,
content,
text,
ButtonRequestType.ResetDevice)
@ -158,8 +159,9 @@ async def show_mnemonic_page(page: int, page_count: int, pages: list):
debug.reset_current_words = [word for _, word in pages[page]]
lines = ['%2d. %s' % (wi + 1, word) for wi, word in pages[page]]
content = Text('Recovery seed', ui.ICON_RESET, ui.MONO, *lines)
content = Scrollpage(content, page, page_count)
text = Text('Recovery seed', ui.ICON_RESET)
text.mono(*lines)
content = Scrollpage(text, page, page_count)
if page + 1 == page_count:
await HoldToConfirmDialog(content)

@ -10,12 +10,10 @@ async def set_u2f_counter(ctx, msg):
if msg.u2f_counter is None:
raise wire.ProcessError('No value provided')
await require_confirm(ctx, Text(
'Set U2F counter', ui.ICON_CONFIG,
'Do you really want to',
'set the U2F counter',
ui.BOLD, 'to %d?' % msg.u2f_counter),
code=ButtonRequestType.ProtectCall)
text = Text('Set U2F counter', ui.ICON_CONFIG)
text.type('Do you really want to', 'set the U2F counter')
text.bold('to %d?' % msg.u2f_counter)
await require_confirm(ctx, text, code=ButtonRequestType.ProtectCall)
storage.set_u2f_counter(msg.u2f_counter)

@ -8,12 +8,11 @@ from apps.common.confirm import require_hold_to_confirm
async def wipe_device(ctx, msg):
await require_hold_to_confirm(ctx, Text(
'Wipe device',
ui.ICON_WIPE,
ui.NORMAL, 'Do you really want to', 'wipe the device?',
ui.NORMAL, '', 'All data will be lost.',
icon_color=ui.RED),
text = Text('Wipe device', ui.ICON_WIPE, icon_color=ui.RED)
text.type('Do you really want to', 'wipe the device?', '')
text.bold('All data will be lost.')
await require_hold_to_confirm(ctx, text,
code=ButtonRequestType.WipeDevice,
button_style=ui.BTN_CANCEL,
loader_style=ui.LDR_DANGER)

@ -30,9 +30,7 @@ async def get_address(ctx, msg):
async def _show_address(ctx, address: str, network: int):
lines = split_address(address)
content = Text(
'Confirm address', ui.ICON_RECEIVE,
ui.NORMAL, '%s network' % get_network_str(network),
ui.MONO, *lines,
icon_color=ui.GREEN)
return await confirm(ctx, content, code=ButtonRequestType.Address, cancel='QR', cancel_style=ui.BTN_KEY)
text = Text('Confirm address', ui.ICON_RECEIVE, icon_color=ui.GREEN)
text.type('%s network' % get_network_str(network))
text.mono(*lines)
return await confirm(ctx, text, code=ButtonRequestType.Address, cancel='QR', cancel_style=ui.BTN_KEY)

@ -22,19 +22,18 @@ async def require_confirm_fee(ctx, action: str, fee: int):
async def require_confirm_content(ctx, headline: str, content: list):
text = Text(headline, ui.ICON_SEND, *content, icon_color=ui.GREEN)
text = Text(headline, ui.ICON_SEND, icon_color=ui.GREEN)
text.type(*content)
await require_confirm(ctx, text, ButtonRequestType.ConfirmOutput)
async def require_confirm_final(ctx, fee: int):
content = Text(
'Final confirm', ui.ICON_SEND,
ui.NORMAL, 'Sign this transaction',
ui.BOLD, 'and pay %s XEM' % format_amount(fee, NEM_MAX_DIVISIBILITY),
ui.NORMAL, 'for network fee?',
icon_color=ui.GREEN)
text = Text('Final confirm', ui.ICON_SEND, icon_color=ui.GREEN)
text.type('Sign this transaction')
text.bold('and pay %s XEM' % format_amount(fee, NEM_MAX_DIVISIBILITY))
text.type('for network fee?')
# we use SignTx, not ConfirmOutput, for compatibility with T1
await require_hold_to_confirm(ctx, content, ButtonRequestType.SignTx)
await require_hold_to_confirm(ctx, text, ButtonRequestType.SignTx)
def split_address(address: str):

@ -67,57 +67,68 @@ async def _show_page(page: int, page_count: int, content):
def _get_mosaic_properties(definition: NEMMosaicDefinition):
properties = []
# description
if definition.description:
t = Text('Confirm properties', ui.ICON_SEND,
ui.BOLD, 'Description:',
ui.NORMAL, *split_words(trim(definition.description, 70), 22))
t = Text('Confirm properties', ui.ICON_SEND)
t.bold('Description:')
t.type(*split_words(trim(definition.description, 70), 22))
properties.append(t)
# transferable
if definition.transferable:
transferable = 'Yes'
else:
transferable = 'No'
t = Text('Confirm properties', ui.ICON_SEND,
ui.BOLD, 'Transferable?',
ui.NORMAL, transferable)
t = Text('Confirm properties', ui.ICON_SEND)
t.bold('Transferable?')
t.type(transferable)
properties.append(t)
# mutable_supply
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)
t = Text('Confirm properties', ui.ICON_SEND)
t.bold('Initial supply:')
t.type(str(definition.supply), imm)
else:
t = Text('Confirm properties', ui.ICON_SEND,
ui.BOLD, 'Initial supply:',
ui.NORMAL, imm)
t = Text('Confirm properties', ui.ICON_SEND)
t.bold('Initial supply:')
t.type(imm)
properties.append(t)
# levy
if definition.levy:
t = Text('Confirm properties', ui.ICON_SEND,
ui.BOLD, 'Levy recipient:',
ui.MONO, *split_address(definition.levy_address))
t = Text('Confirm properties', ui.ICON_SEND)
t.bold('Levy recipient:')
t.mono(*split_address(definition.levy_address))
properties.append(t)
t = Text('Confirm properties', ui.ICON_SEND,
ui.BOLD, 'Levy fee:',
ui.NORMAL, str(definition.fee),
ui.BOLD, 'Levy divisibility:',
ui.NORMAL, str(definition.divisibility))
t = Text('Confirm properties', ui.ICON_SEND)
t.bold('Levy fee:')
t.type(str(definition.fee))
t.bold('Levy divisibility:')
t.type(str(definition.divisibility))
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)
t = Text('Confirm properties', ui.ICON_SEND)
t.bold('Levy namespace:')
t.type(definition.levy_namespace)
t.bold('Levy mosaic:')
t.type(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)
t = Text('Confirm properties', ui.ICON_SEND)
t.bold('Levy type:')
t.type(levy_type)
properties.append(t)
return properties

@ -42,8 +42,7 @@ async def ask_aggregate_modification(ctx, common: NEMTransactionCommon, mod: NEM
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)
text = Text('Confirm address', ui.ICON_SEND, icon_color=ui.GREEN)
text.type(action)
text.mono(*split_address(address))
await require_confirm(ctx, text, ButtonRequestType.ConfirmOutput)

@ -30,38 +30,31 @@ async def ask_transfer_mosaic(ctx, common: NEMTransactionCommon, transfer: NEMTr
mosaic_quantity = mosaic.quantity * transfer.amount / NEM_MOSAIC_AMOUNT_DIVISOR
if definition:
msg = Text('Confirm mosaic', ui.ICON_SEND,
'Confirm transfer of',
ui.BOLD, format_amount(mosaic_quantity, definition['divisibility']) + definition['ticker'],
ui.NORMAL, 'of',
ui.BOLD, definition['name'],
icon_color=ui.GREEN)
msg = Text('Confirm mosaic', ui.ICON_SEND, icon_color=ui.GREEN)
msg.type('Confirm transfer of')
msg.bold(format_amount(mosaic_quantity, definition['divisibility']) + definition['ticker'])
msg.type('of')
msg.bold(definition['name'])
await require_confirm(ctx, msg, ButtonRequestType.ConfirmOutput)
if 'levy' in definition and 'fee' in definition:
levy_msg = _get_levy_msg(definition, mosaic_quantity, common.network)
msg = Text('Confirm mosaic', ui.ICON_SEND,
'Confirm mosaic',
'levy fee of',
ui.BOLD, levy_msg,
icon_color=ui.GREEN)
msg = Text('Confirm mosaic', ui.ICON_SEND, icon_color=ui.GREEN)
msg.type('Confirm mosaic', 'levy fee of')
msg.bold(levy_msg)
await require_confirm(ctx, msg, ButtonRequestType.ConfirmOutput)
else:
msg = Text('Confirm mosaic', ui.ICON_SEND,
ui.BOLD, 'Unknown mosaic!',
ui.NORMAL, *split_words('Divisibility and levy cannot be shown for unknown mosaics', 22),
icon_color=ui.RED)
msg = Text('Confirm mosaic', ui.ICON_SEND, icon_color=ui.RED)
msg.bold('Unknown mosaic!')
msg.type(*split_words('Divisibility and levy cannot be shown for unknown mosaics', 22))
await require_confirm(ctx, msg, ButtonRequestType.ConfirmOutput)
msg = Text('Confirm mosaic', ui.ICON_SEND,
ui.NORMAL, 'Confirm transfer of',
ui.BOLD, '%s raw units' % mosaic_quantity,
ui.NORMAL, 'of',
ui.BOLD, '%s.%s' % (mosaic.namespace, mosaic.mosaic),
icon_color=ui.GREEN)
msg = Text('Confirm mosaic', ui.ICON_SEND, icon_color=ui.GREEN)
msg.type('Confirm transfer of')
msg.bold('%s raw units' % mosaic_quantity)
msg.type('of')
msg.bold('%s.%s' % (mosaic.namespace, mosaic.mosaic))
await require_confirm(ctx, msg, ButtonRequestType.ConfirmOutput)
@ -102,12 +95,11 @@ async def ask_importance_transfer(ctx, common: NEMTransactionCommon, imp: NEMImp
async def _require_confirm_transfer(ctx, recipient, value):
content = Text('Confirm transfer', ui.ICON_SEND,
ui.BOLD, 'Send %s XEM' % format_amount(value, NEM_MAX_DIVISIBILITY),
ui.NORMAL, 'to',
ui.MONO, *split_address(recipient),
icon_color=ui.GREEN)
await require_confirm(ctx, content, ButtonRequestType.ConfirmOutput)
text = Text('Confirm transfer', ui.ICON_SEND, icon_color=ui.GREEN)
text.bold('Send %s XEM' % format_amount(value, NEM_MAX_DIVISIBILITY))
text.type('to')
text.mono(*split_address(recipient))
await require_confirm(ctx, text, ButtonRequestType.ConfirmOutput)
async def _require_confirm_payload(ctx, payload: bytes, encrypt=False):
@ -116,13 +108,11 @@ async def _require_confirm_payload(ctx, payload: bytes, encrypt=False):
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)
text = Text('Confirm payload', ui.ICON_SEND, icon_color=ui.GREEN)
text.bold('Encrypted:')
text.type(*split_words(payload, 22))
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)
text = Text('Confirm payload', ui.ICON_SEND, icon_color=ui.RED)
text.bold('Unencrypted:')
text.type(*split_words(payload, 22))
await require_confirm(ctx, text, ButtonRequestType.ConfirmOutput)

@ -20,8 +20,9 @@ async def cipher_key_value(ctx, msg):
title = 'Encrypt value'
else:
title = 'Decrypt value'
lines = split_words(msg.key, ui.WIDTH - 2 * TEXT_MARGIN_LEFT, metric=lambda x: ui.display.text_width(x, ui.NORMAL))
await require_confirm(ctx, Text(title, ui.ICON_DEFAULT, max_lines=5, *lines))
text = Text(title, ui.ICON_DEFAULT)
text.type(msg.key)
await require_confirm(ctx, text)
node = await seed.derive_node(ctx, msg.address_n)
value = compute_cipher_key_value(msg, node.private_key())

@ -30,9 +30,9 @@ async def get_ecdh_session_key(ctx, msg):
async def require_confirm_ecdh_session_key(ctx, identity):
lines = chunks(serialize_identity_without_proto(identity), 18)
proto = identity.proto.upper() if identity.proto else 'identity'
header = 'Decrypt %s' % (proto,)
content = Text(header, ui.ICON_DEFAULT, ui.MONO, *lines, max_lines=5)
await require_confirm(ctx, content)
text = Text('Decrypt %s' % proto, ui.ICON_DEFAULT)
text.mono(*lines)
await require_confirm(ctx, text)
def get_ecdh_path(identity: str, index: int):

@ -8,11 +8,10 @@ from apps.common.confirm import require_confirm
async def get_entropy(ctx, msg):
await require_confirm(ctx, Text(
'Confirm entropy', ui.ICON_DEFAULT,
ui.BOLD, 'Do you really want', 'to send entropy?',
ui.NORMAL, 'Continue only if you', 'know what you are doing!'),
code=ButtonRequestType.ProtectCall)
text = Text('Confirm entropy', ui.ICON_DEFAULT)
text.bold('Do you really want', 'to send entropy?')
text.type('Continue only if you', 'know what you are doing!')
await require_confirm(ctx, text, code=ButtonRequestType.ProtectCall)
size = min(msg.size, 1024)
entropy = random.bytes(size)

@ -38,8 +38,9 @@ async def get_public_key(ctx, msg):
async def _show_pubkey(ctx, pubkey: bytes):
lines = chunks(hexlify(pubkey).decode(), 18)
content = Text('Confirm public key', ui.ICON_RECEIVE, ui.MONO, *lines, icon_color=ui.GREEN)
text = Text('Confirm public key', ui.ICON_RECEIVE, icon_color=ui.GREEN)
text.mono(*lines)
return await require_confirm(
ctx,
content,
text,
code=ButtonRequestType.PublicKey)

@ -53,9 +53,9 @@ async def require_confirm_sign_identity(ctx, identity, challenge_visual):
lines.extend(chunks(serialize_identity_without_proto(identity), 18))
proto = identity.proto.upper() if identity.proto else 'identity'
header = 'Sign %s' % proto
content = Text(header, ui.ICON_DEFAULT, *lines, max_lines=5)
await require_confirm(ctx, content)
text = Text('Sign %s' % proto, ui.ICON_DEFAULT)
text.type(*lines)
await require_confirm(ctx, text)
def serialize_identity(identity):

@ -39,5 +39,6 @@ async def sign_message(ctx, msg):
async def require_confirm_sign_message(ctx, message):
message = split_message(message)
content = Text('Sign message', ui.ICON_DEFAULT, max_lines=5, *message)
await require_confirm(ctx, content)
text = Text('Sign message', ui.ICON_DEFAULT)
text.type(*message)
await require_confirm(ctx, text)

@ -26,40 +26,38 @@ async def confirm_output(ctx, output, coin):
data = hexlify(output.op_return_data).decode()
if len(data) >= 18 * 5:
data = data[:(18 * 5 - 3)] + '...'
content = Text('OP_RETURN', ui.ICON_SEND,
ui.MONO, *split_op_return(data), icon_color=ui.GREEN)
text = Text('OP_RETURN', ui.ICON_SEND, icon_color=ui.GREEN)
text.mono(*split_op_return(data))
else:
address = output.address
address_short = addresses.address_short(coin, address)
content = Text('Confirm sending', ui.ICON_SEND,
ui.NORMAL, format_coin_amount(output.amount, coin) + ' to',
ui.MONO, *split_address(address_short), icon_color=ui.GREEN)
return await confirm(ctx, content, ButtonRequestType.ConfirmOutput)
text = Text('Confirm sending', ui.ICON_SEND, icon_color=ui.GREEN)
text.type(format_coin_amount(output.amount, coin) + ' to')
text.mono(*split_address(address_short))
return await confirm(ctx, text, ButtonRequestType.ConfirmOutput)
async def confirm_total(ctx, spending, fee, coin):
content = Text('Confirm transaction', ui.ICON_SEND,
'Total amount:',
ui.BOLD, format_coin_amount(spending, coin),
ui.NORMAL, 'including fee:',
ui.BOLD, format_coin_amount(fee, coin), icon_color=ui.GREEN)
return await hold_to_confirm(ctx, content, ButtonRequestType.SignTx)
text = Text('Confirm transaction', ui.ICON_SEND, icon_color=ui.GREEN)
text.type('Total amount:')
text.bold(format_coin_amount(spending, coin))
text.type('including fee:')
text.bold(format_coin_amount(fee, coin))
return await hold_to_confirm(ctx, text, ButtonRequestType.SignTx)
async def confirm_feeoverthreshold(ctx, fee, coin):
content = Text('High fee', ui.ICON_SEND,
'The fee of',
ui.BOLD, format_coin_amount(fee, coin),
ui.NORMAL, 'is unexpectedly high.',
'Continue?', icon_color=ui.GREEN)
return await confirm(ctx, content, ButtonRequestType.FeeOverThreshold)
text = Text('High fee', ui.ICON_SEND, icon_color=ui.GREEN)
text.type('The fee of')
text.bold(format_coin_amount(fee, coin))
text.type('is unexpectedly high.', 'Continue?')
return await confirm(ctx, text, ButtonRequestType.FeeOverThreshold)
async def confirm_foreign_address(ctx, address_n, coin):
content = Text('Confirm sending', ui.ICON_SEND,
'Trying to spend',
'coins from another chain.',
'Continue?', icon_color=ui.RED)
return await confirm(ctx, content, ButtonRequestType.SignTx)
text = Text('Confirm sending', ui.ICON_SEND, icon_color=ui.RED)
text.type(
'Trying to spend',
'coins from another chain.',
'Continue?')
return await confirm(ctx, text, ButtonRequestType.SignTx)

@ -57,10 +57,10 @@ async def verify_message(ctx, msg):
async def require_confirm_verify_message(ctx, address, message):
lines = split_address(address)
content = Text('Confirm address', ui.ICON_DEFAULT, ui.MONO, *lines)
await require_confirm(ctx, content)
text = Text('Confirm address', ui.ICON_DEFAULT)
text.mono(*split_address(address))
await require_confirm(ctx, text)
message = split_message(message)
content = Text('Verify message', ui.ICON_DEFAULT, max_lines=5, *message)
await require_confirm(ctx, content)
text = Text('Verify message', ui.ICON_DEFAULT)
text.type(*split_message(message))
await require_confirm(ctx, text)

Loading…
Cancel
Save