mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-02-24 13:22:05 +00:00
apps: use mutable Text API
This commit is contained in:
parent
49e75851c7
commit
b3d3da7f7a
@ -10,10 +10,11 @@ from trezor.utils import chunks
|
|||||||
|
|
||||||
async def show_address(ctx, address: str):
|
async def show_address(ctx, address: str):
|
||||||
lines = split_address(address)
|
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(
|
return await confirm(
|
||||||
ctx,
|
ctx,
|
||||||
content,
|
text,
|
||||||
code=ButtonRequestType.Address,
|
code=ButtonRequestType.Address,
|
||||||
cancel='QR',
|
cancel='QR',
|
||||||
cancel_style=ui.BTN_KEY)
|
cancel_style=ui.BTN_KEY)
|
||||||
@ -24,9 +25,9 @@ async def show_qr(ctx, address: str):
|
|||||||
qr_y = const(115)
|
qr_y = const(115)
|
||||||
qr_coef = const(4)
|
qr_coef = const(4)
|
||||||
|
|
||||||
content = Container(
|
qr = Qr(address, (qr_x, qr_y), qr_coef)
|
||||||
Qr(address, (qr_x, qr_y), qr_coef),
|
text = Text('Confirm address', ui.ICON_RECEIVE, icon_color=ui.GREEN)
|
||||||
Text('Confirm address', ui.ICON_RECEIVE, ui.MONO, icon_color=ui.GREEN))
|
content = Container(qr, text)
|
||||||
return await confirm(
|
return await confirm(
|
||||||
ctx,
|
ctx,
|
||||||
content,
|
content,
|
||||||
|
@ -13,9 +13,8 @@ from apps.common.cache import get_state
|
|||||||
|
|
||||||
@ui.layout
|
@ui.layout
|
||||||
async def request_passphrase_entry(ctx):
|
async def request_passphrase_entry(ctx):
|
||||||
text = Text(
|
text = Text('Enter passphrase', ui.ICON_CONFIG)
|
||||||
'Enter passphrase', ui.ICON_CONFIG,
|
text.type('Where to enter your', 'passphrase?')
|
||||||
'Where to enter your', 'passphrase?')
|
|
||||||
text.render()
|
text.render()
|
||||||
|
|
||||||
ack = await ctx.call(
|
ack = await ctx.call(
|
||||||
@ -32,9 +31,8 @@ async def request_passphrase_entry(ctx):
|
|||||||
@ui.layout
|
@ui.layout
|
||||||
async def request_passphrase_ack(ctx, on_device):
|
async def request_passphrase_ack(ctx, on_device):
|
||||||
if not on_device:
|
if not on_device:
|
||||||
text = Text(
|
text = Text('Passphrase entry', ui.ICON_CONFIG)
|
||||||
'Passphrase entry', ui.ICON_CONFIG,
|
text.type('Please, type passphrase', 'on connected host.')
|
||||||
'Please, type passphrase', 'on connected host.')
|
|
||||||
text.render()
|
text.render()
|
||||||
|
|
||||||
req = PassphraseRequest(on_device=on_device)
|
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):
|
async def require_confirm_tx(ctx, to, value, chain_id, token=None, tx_type=None):
|
||||||
if to:
|
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:
|
else:
|
||||||
str_to = 'new contract?'
|
to_str = 'new contract?'
|
||||||
content = Text('Confirm sending', ui.ICON_SEND,
|
text = Text('Confirm sending', ui.ICON_SEND, icon_color=ui.GREEN)
|
||||||
ui.BOLD, format_ethereum_amount(value, token, chain_id, tx_type),
|
text.bold(format_ethereum_amount(value, token, chain_id, tx_type))
|
||||||
ui.NORMAL, 'to',
|
text.type('to')
|
||||||
ui.MONO, *split_address(str_to),
|
text.mono(*split_address(to_str))
|
||||||
icon_color=ui.GREEN)
|
# we use SignTx, not ConfirmOutput, for compatibility with T1
|
||||||
await require_confirm(ctx, content, ButtonRequestType.SignTx) # 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):
|
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,
|
text = Text('Confirm transaction', ui.ICON_SEND, icon_color=ui.GREEN)
|
||||||
ui.BOLD, format_ethereum_amount(spending, token, chain_id, tx_type),
|
text.bold(format_ethereum_amount(spending, token, chain_id, tx_type))
|
||||||
ui.NORMAL, 'Gas price:',
|
text.type('Gas price:')
|
||||||
ui.BOLD, format_ethereum_amount(gas_price, None, chain_id, tx_type),
|
text.bold(format_ethereum_amount(gas_price, None, chain_id, tx_type))
|
||||||
ui.NORMAL, 'Maximum fee:',
|
text.type('Maximum fee:')
|
||||||
ui.BOLD, format_ethereum_amount(gas_price * gas_limit, None, chain_id, tx_type),
|
text.bold(format_ethereum_amount(gas_price * gas_limit, None, chain_id, tx_type))
|
||||||
icon_color=ui.GREEN)
|
await require_hold_to_confirm(ctx, text, ButtonRequestType.SignTx)
|
||||||
await require_hold_to_confirm(ctx, content, ButtonRequestType.SignTx)
|
|
||||||
|
|
||||||
|
|
||||||
def split_data(data):
|
def split_data(data):
|
||||||
@ -39,14 +38,14 @@ def split_data(data):
|
|||||||
|
|
||||||
|
|
||||||
async def require_confirm_data(ctx, data, data_total):
|
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:
|
if data_total > 36:
|
||||||
str_data = str_data[:-2] + '..'
|
data_str = data_str[:-2] + '..'
|
||||||
content = Text('Confirm data', ui.ICON_SEND,
|
text = Text('Confirm data', ui.ICON_SEND, icon_color=ui.GREEN)
|
||||||
ui.BOLD, 'Size: %d bytes' % data_total,
|
text.bold('Size: %d bytes' % data_total)
|
||||||
ui.MONO, *split_data(str_data),
|
text.mono(*split_data(data_str))
|
||||||
icon_color=ui.GREEN)
|
# we use SignTx, not ConfirmOutput, for compatibility with T1
|
||||||
await require_confirm(ctx, content, ButtonRequestType.SignTx) # we use SignTx, not ConfirmOutput, for compatibility with T1
|
await require_confirm(ctx, text, ButtonRequestType.SignTx)
|
||||||
|
|
||||||
|
|
||||||
def split_address(address):
|
def split_address(address):
|
||||||
|
@ -37,5 +37,6 @@ async def ethereum_sign_message(ctx, msg):
|
|||||||
|
|
||||||
async def require_confirm_sign_message(ctx, message):
|
async def require_confirm_sign_message(ctx, message):
|
||||||
message = split_message(message)
|
message = split_message(message)
|
||||||
content = Text('Sign ETH message', ui.ICON_DEFAULT, max_lines=5, *message)
|
text = Text('Sign ETH message', ui.ICON_DEFAULT)
|
||||||
await require_confirm(ctx, content)
|
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):
|
async def require_confirm_verify_message(ctx, address, message):
|
||||||
lines = split_address(address)
|
text = Text('Confirm address', ui.ICON_DEFAULT)
|
||||||
content = Text('Confirm address', ui.ICON_DEFAULT, ui.MONO, *lines)
|
text.mono(*split_address(address))
|
||||||
await require_confirm(ctx, content)
|
await require_confirm(ctx, text)
|
||||||
|
|
||||||
message = split_message(message)
|
text = Text('Verify message', ui.ICON_DEFAULT)
|
||||||
content = Text('Verify message', ui.ICON_DEFAULT, max_lines=5, *message)
|
text.mono(*split_message(message))
|
||||||
await require_confirm(ctx, content)
|
await require_confirm(ctx, text)
|
||||||
|
@ -391,12 +391,8 @@ class ConfirmState:
|
|||||||
from trezor.ui.text import Text
|
from trezor.ui.text import Text
|
||||||
|
|
||||||
if bytes(self.app_id) == _BOGUS_APPID:
|
if bytes(self.app_id) == _BOGUS_APPID:
|
||||||
text = Text(
|
text = Text('U2F mismatch', ui.ICON_WRONG, icon_color=ui.RED)
|
||||||
'U2F mismatch', ui.ICON_WRONG,
|
text.type('Another U2F device', 'was used to register', 'in this application.')
|
||||||
'Another U2F device',
|
|
||||||
'was used to register',
|
|
||||||
'in this application.',
|
|
||||||
icon_color=ui.RED)
|
|
||||||
text.render()
|
text.render()
|
||||||
await loop.sleep(3 * 1000 * 1000)
|
await loop.sleep(3 * 1000 * 1000)
|
||||||
self.confirmed = True
|
self.confirmed = True
|
||||||
|
@ -9,28 +9,25 @@ from .helpers import get_vote_tx_text
|
|||||||
|
|
||||||
|
|
||||||
async def require_confirm_tx(ctx, to, value):
|
async def require_confirm_tx(ctx, to, value):
|
||||||
content = Text('Confirm sending', ui.ICON_SEND,
|
text = Text('Confirm sending', ui.ICON_SEND, icon_color=ui.GREEN)
|
||||||
ui.BOLD, format_amount(value),
|
text.bold(format_amount(value))
|
||||||
ui.NORMAL, 'to',
|
text.type('to')
|
||||||
ui.MONO, *split_address(to),
|
text.mono(*split_address(to))
|
||||||
icon_color=ui.GREEN)
|
return await require_confirm(ctx, text, ButtonRequestType.SignTx)
|
||||||
return await require_confirm(ctx, content, ButtonRequestType.SignTx)
|
|
||||||
|
|
||||||
|
|
||||||
async def require_confirm_delegate_registration(ctx, delegate_name):
|
async def require_confirm_delegate_registration(ctx, delegate_name):
|
||||||
content = Text('Confirm transaction', ui.ICON_SEND,
|
text = Text('Confirm transaction', ui.ICON_SEND, icon_color=ui.GREEN)
|
||||||
'Do you really want to',
|
text.type('Do you really want to')
|
||||||
'register a delegate?',
|
text.type('register a delegate?')
|
||||||
ui.BOLD, *chunks(delegate_name, 20),
|
text.bold(*chunks(delegate_name, 20))
|
||||||
icon_color=ui.GREEN)
|
return await require_confirm(ctx, text, ButtonRequestType.SignTx)
|
||||||
return await require_confirm(ctx, content, ButtonRequestType.SignTx)
|
|
||||||
|
|
||||||
|
|
||||||
async def require_confirm_vote_tx(ctx, votes):
|
async def require_confirm_vote_tx(ctx, votes):
|
||||||
content = Text('Confirm transaction', ui.ICON_SEND,
|
text = Text('Confirm transaction', ui.ICON_SEND, icon_color=ui.GREEN)
|
||||||
*get_vote_tx_text(votes),
|
text.type(*get_vote_tx_text(votes))
|
||||||
icon_color=ui.GREEN)
|
return await require_confirm(ctx, text, ButtonRequestType.SignTx)
|
||||||
return await require_confirm(ctx, content, ButtonRequestType.SignTx)
|
|
||||||
|
|
||||||
|
|
||||||
async def require_confirm_public_key(ctx, public_key):
|
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):
|
async def require_confirm_multisig(ctx, multisignature):
|
||||||
content = Text('Confirm transaction', ui.ICON_SEND,
|
text = Text('Confirm transaction', ui.ICON_SEND, icon_color=ui.GREEN)
|
||||||
('Keys group length: %s' % len(multisignature.keys_group)),
|
text.type('Keys group length: %s' % len(multisignature.keys_group))
|
||||||
('Life time: %s' % multisignature.life_time),
|
text.type('Life time: %s' % multisignature.life_time)
|
||||||
('Min: %s' % multisignature.min),
|
text.type('Min: %s' % multisignature.min)
|
||||||
icon_color=ui.GREEN)
|
return await require_confirm(ctx, text, ButtonRequestType.SignTx)
|
||||||
return await require_confirm(ctx, content, ButtonRequestType.SignTx)
|
|
||||||
|
|
||||||
|
|
||||||
async def require_confirm_fee(ctx, value, fee):
|
async def require_confirm_fee(ctx, value, fee):
|
||||||
content = Text('Confirm transaction', ui.ICON_SEND,
|
text = Text('Confirm transaction', ui.ICON_SEND, icon_color=ui.GREEN)
|
||||||
ui.BOLD, format_amount(value),
|
text.bold(format_amount(value))
|
||||||
ui.NORMAL, 'fee:',
|
text.type('fee:')
|
||||||
ui.BOLD, format_amount(fee),
|
text.bold(format_amount(fee))
|
||||||
icon_color=ui.GREEN)
|
await require_hold_to_confirm(ctx, text, ButtonRequestType.ConfirmOutput)
|
||||||
await require_hold_to_confirm(ctx, content, ButtonRequestType.ConfirmOutput)
|
|
||||||
|
|
||||||
|
|
||||||
def format_amount(value):
|
def format_amount(value):
|
||||||
|
@ -39,6 +39,6 @@ async def lisk_sign_message(ctx, msg):
|
|||||||
|
|
||||||
|
|
||||||
async def require_confirm_sign_message(ctx, message):
|
async def require_confirm_sign_message(ctx, message):
|
||||||
message = split_message(message)
|
text = Text('Sign Lisk message', ui.ICON_DEFAULT)
|
||||||
content = Text('Sign Lisk message', ui.ICON_DEFAULT, max_lines=5, *message)
|
text.type(*split_message(message))
|
||||||
await require_confirm(ctx, content)
|
await require_confirm(ctx, text)
|
||||||
|
@ -13,40 +13,16 @@ async def apply_settings(ctx, msg):
|
|||||||
if msg.homescreen is not None:
|
if msg.homescreen is not None:
|
||||||
if len(msg.homescreen) > storage.HOMESCREEN_MAXSIZE:
|
if len(msg.homescreen) > storage.HOMESCREEN_MAXSIZE:
|
||||||
raise wire.DataError('Homescreen is too complex')
|
raise wire.DataError('Homescreen is too complex')
|
||||||
await require_confirm(ctx, Text(
|
await require_confirm_change_homescreen(ctx)
|
||||||
'Change homescreen', ui.ICON_CONFIG,
|
|
||||||
'Do you really want to', 'change homescreen?'),
|
|
||||||
code=ButtonRequestType.ProtectCall)
|
|
||||||
|
|
||||||
# TODO: split label (bold) and '?' (normal) once we support mixed styles on one line
|
|
||||||
if msg.label is not None:
|
if msg.label is not None:
|
||||||
await require_confirm(ctx, Text(
|
await require_confirm_change_label(ctx, msg.label)
|
||||||
'Change label', ui.ICON_CONFIG,
|
|
||||||
'Do you really want to', 'change label to',
|
|
||||||
ui.BOLD, '%s?' % msg.label),
|
|
||||||
code=ButtonRequestType.ProtectCall)
|
|
||||||
|
|
||||||
if msg.use_passphrase is not None:
|
if msg.use_passphrase is not None:
|
||||||
await require_confirm(ctx, Text(
|
await require_confirm_change_passphrase(ctx, msg.use_passphrase)
|
||||||
'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)
|
|
||||||
|
|
||||||
if msg.passphrase_source is not None:
|
if msg.passphrase_source is not None:
|
||||||
if msg.passphrase_source == PassphraseSourceType.DEVICE:
|
await require_confirm_change_passphrase_source(ctx, msg.passphrase_source)
|
||||||
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)
|
|
||||||
|
|
||||||
storage.load_settings(label=msg.label,
|
storage.load_settings(label=msg.label,
|
||||||
use_passphrase=msg.use_passphrase,
|
use_passphrase=msg.use_passphrase,
|
||||||
@ -54,3 +30,37 @@ async def apply_settings(ctx, msg):
|
|||||||
passphrase_source=msg.passphrase_source)
|
passphrase_source=msg.passphrase_source)
|
||||||
|
|
||||||
return Success(message='Settings applied')
|
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()
|
has_pin = config.has_pin()
|
||||||
|
|
||||||
if msg.remove and has_pin: # removing pin
|
if msg.remove and has_pin: # removing pin
|
||||||
return require_confirm(ctx, Text(
|
text = Text('Remove PIN', ui.ICON_CONFIG)
|
||||||
'Remove PIN', ui.ICON_CONFIG,
|
text.type('Do you really want to')
|
||||||
'Do you really want to', ui.BOLD,
|
text.bold('remove current PIN?')
|
||||||
'remove current PIN?'))
|
return require_confirm(ctx, text)
|
||||||
|
|
||||||
if not msg.remove and has_pin: # changing pin
|
if not msg.remove and has_pin: # changing pin
|
||||||
return require_confirm(ctx, Text(
|
text = Text('Remove PIN', ui.ICON_CONFIG)
|
||||||
'Change PIN', ui.ICON_CONFIG,
|
text.type('Do you really want to')
|
||||||
'Do you really want to', ui.BOLD,
|
text.bold('change current PIN?')
|
||||||
'change current PIN?'))
|
return require_confirm(ctx, text)
|
||||||
|
|
||||||
if not msg.remove and not has_pin: # setting new pin
|
if not msg.remove and not has_pin: # setting new pin
|
||||||
return require_confirm(ctx, Text(
|
text = Text('Remove PIN', ui.ICON_CONFIG)
|
||||||
'Change PIN', ui.ICON_CONFIG,
|
text.type('Do you really want to')
|
||||||
'Do you really want to', ui.BOLD,
|
text.bold('set new PIN?')
|
||||||
'set new PIN?'))
|
return require_confirm(ctx, text)
|
||||||
|
|
||||||
|
|
||||||
async def request_pin_confirm(ctx, *args, **kwargs):
|
async def request_pin_confirm(ctx, *args, **kwargs):
|
||||||
@ -79,11 +79,9 @@ async def request_pin_ack(ctx, *args, **kwargs):
|
|||||||
|
|
||||||
@ui.layout
|
@ui.layout
|
||||||
async def pin_mismatch():
|
async def pin_mismatch():
|
||||||
text = Text(
|
text = Text('PIN mismatch', ui.ICON_WRONG, icon_color=ui.RED)
|
||||||
'PIN mismatch', ui.ICON_WRONG,
|
text.type('Entered PINs do not', 'match each other.')
|
||||||
'Entered PINs do not',
|
text.type('')
|
||||||
'match each other.',
|
text.type('Please, try again...')
|
||||||
'',
|
|
||||||
'Please, try again...', icon_color=ui.RED)
|
|
||||||
text.render()
|
text.render()
|
||||||
await loop.sleep(3 * 1000 * 1000)
|
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):
|
if not msg.skip_checksum and not bip39.check(msg.mnemonic):
|
||||||
raise wire.ProcessError('Mnemonic is not valid')
|
raise wire.ProcessError('Mnemonic is not valid')
|
||||||
|
|
||||||
await require_confirm(ctx, Text(
|
text = Text('Loading seed', ui.ICON_DEFAULT)
|
||||||
'Loading seed', ui.ICON_DEFAULT,
|
text.bold('Loading private seed', 'is not recommended.')
|
||||||
ui.BOLD, 'Loading private seed', 'is not recommended.',
|
text.type('Continue only if you', 'know what you are doing!')
|
||||||
ui.NORMAL, 'Continue only if you', 'know what you are doing!'))
|
await require_confirm(ctx, text)
|
||||||
|
|
||||||
storage.load_mnemonic(
|
storage.load_mnemonic(
|
||||||
mnemonic=msg.mnemonic, needs_backup=True)
|
mnemonic=msg.mnemonic, needs_backup=True)
|
||||||
|
@ -61,9 +61,9 @@ async def recovery_device(ctx, msg):
|
|||||||
async def request_wordcount(ctx):
|
async def request_wordcount(ctx):
|
||||||
await ctx.call(ButtonRequest(code=MnemonicWordCount), ButtonAck)
|
await ctx.call(ButtonRequest(code=MnemonicWordCount), ButtonAck)
|
||||||
|
|
||||||
content = Text('Device recovery', ui.ICON_RECOVERY, 'Number of words?')
|
text = Text('Device recovery', ui.ICON_RECOVERY)
|
||||||
select = WordSelector(content)
|
text.type('Number of words?')
|
||||||
count = await ctx.wait(select)
|
count = await ctx.wait(WordSelector(text))
|
||||||
|
|
||||||
return count
|
return count
|
||||||
|
|
||||||
|
@ -88,56 +88,57 @@ def generate_mnemonic(strength: int,
|
|||||||
|
|
||||||
|
|
||||||
async def show_warning(ctx):
|
async def show_warning(ctx):
|
||||||
content = Text(
|
text = Text('Backup your seed', ui.ICON_NOCOPY)
|
||||||
'Backup your seed', ui.ICON_NOCOPY,
|
text.type(
|
||||||
'Never make a digital',
|
'Never make a digital',
|
||||||
'copy of your recovery',
|
'copy of your recovery',
|
||||||
'seed and never upload',
|
'seed and never upload',
|
||||||
'it online!')
|
'it online!')
|
||||||
await require_confirm(
|
await require_confirm(
|
||||||
ctx,
|
ctx,
|
||||||
content,
|
text,
|
||||||
ButtonRequestType.ResetDevice,
|
ButtonRequestType.ResetDevice,
|
||||||
confirm='I understand',
|
confirm='I understand',
|
||||||
cancel=None)
|
cancel=None)
|
||||||
|
|
||||||
|
|
||||||
async def show_wrong_entry(ctx):
|
async def show_wrong_entry(ctx):
|
||||||
content = Text(
|
text = Text('Wrong entry!', ui.ICON_WRONG, icon_color=ui.RED)
|
||||||
'Wrong entry!', ui.ICON_WRONG,
|
text.type(
|
||||||
'You have entered',
|
'You have entered',
|
||||||
'wrong seed word.',
|
'wrong seed word.',
|
||||||
'Please check again.', icon_color=ui.RED)
|
'Please check again.')
|
||||||
await require_confirm(
|
await require_confirm(
|
||||||
ctx,
|
ctx,
|
||||||
content,
|
text,
|
||||||
ButtonRequestType.ResetDevice,
|
ButtonRequestType.ResetDevice,
|
||||||
confirm='Check again',
|
confirm='Check again',
|
||||||
cancel=None)
|
cancel=None)
|
||||||
|
|
||||||
|
|
||||||
async def show_success(ctx):
|
async def show_success(ctx):
|
||||||
content = Text(
|
text = Text('Backup is done!', ui.ICON_CONFIRM, icon_color=ui.GREEN)
|
||||||
'Backup is done!', ui.ICON_CONFIRM,
|
text.type(
|
||||||
'Never make a digital',
|
'Never make a digital',
|
||||||
'copy of your recovery',
|
'copy of your recovery',
|
||||||
'seed and never upload',
|
'seed and never upload',
|
||||||
'it online!', icon_color=ui.GREEN)
|
'it online!')
|
||||||
await require_confirm(
|
await require_confirm(
|
||||||
ctx,
|
ctx,
|
||||||
content,
|
text,
|
||||||
ButtonRequestType.ResetDevice,
|
ButtonRequestType.ResetDevice,
|
||||||
confirm='Finish setup',
|
confirm='Finish setup',
|
||||||
cancel=None)
|
cancel=None)
|
||||||
|
|
||||||
|
|
||||||
async def show_entropy(ctx, entropy: bytes):
|
async def show_entropy(ctx, entropy: bytes):
|
||||||
estr = hexlify(entropy).decode()
|
entropy_str = hexlify(entropy).decode()
|
||||||
lines = chunks(estr, 16)
|
lines = chunks(entropy_str, 16)
|
||||||
content = Text('Internal entropy', ui.ICON_RESET, ui.MONO, *lines)
|
text = Text('Internal entropy', ui.ICON_RESET)
|
||||||
|
text.mono(*lines)
|
||||||
await require_confirm(
|
await require_confirm(
|
||||||
ctx,
|
ctx,
|
||||||
content,
|
text,
|
||||||
ButtonRequestType.ResetDevice)
|
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]]
|
debug.reset_current_words = [word for _, word in pages[page]]
|
||||||
|
|
||||||
lines = ['%2d. %s' % (wi + 1, word) for wi, 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)
|
text = Text('Recovery seed', ui.ICON_RESET)
|
||||||
content = Scrollpage(content, page, page_count)
|
text.mono(*lines)
|
||||||
|
content = Scrollpage(text, page, page_count)
|
||||||
|
|
||||||
if page + 1 == page_count:
|
if page + 1 == page_count:
|
||||||
await HoldToConfirmDialog(content)
|
await HoldToConfirmDialog(content)
|
||||||
|
@ -10,12 +10,10 @@ async def set_u2f_counter(ctx, msg):
|
|||||||
if msg.u2f_counter is None:
|
if msg.u2f_counter is None:
|
||||||
raise wire.ProcessError('No value provided')
|
raise wire.ProcessError('No value provided')
|
||||||
|
|
||||||
await require_confirm(ctx, Text(
|
text = Text('Set U2F counter', ui.ICON_CONFIG)
|
||||||
'Set U2F counter', ui.ICON_CONFIG,
|
text.type('Do you really want to', 'set the U2F counter')
|
||||||
'Do you really want to',
|
text.bold('to %d?' % msg.u2f_counter)
|
||||||
'set the U2F counter',
|
await require_confirm(ctx, text, code=ButtonRequestType.ProtectCall)
|
||||||
ui.BOLD, 'to %d?' % msg.u2f_counter),
|
|
||||||
code=ButtonRequestType.ProtectCall)
|
|
||||||
|
|
||||||
storage.set_u2f_counter(msg.u2f_counter)
|
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):
|
async def wipe_device(ctx, msg):
|
||||||
|
|
||||||
await require_hold_to_confirm(ctx, Text(
|
text = Text('Wipe device', ui.ICON_WIPE, icon_color=ui.RED)
|
||||||
'Wipe device',
|
text.type('Do you really want to', 'wipe the device?', '')
|
||||||
ui.ICON_WIPE,
|
text.bold('All data will be lost.')
|
||||||
ui.NORMAL, 'Do you really want to', 'wipe the device?',
|
|
||||||
ui.NORMAL, '', 'All data will be lost.',
|
await require_hold_to_confirm(ctx, text,
|
||||||
icon_color=ui.RED),
|
|
||||||
code=ButtonRequestType.WipeDevice,
|
code=ButtonRequestType.WipeDevice,
|
||||||
button_style=ui.BTN_CANCEL,
|
button_style=ui.BTN_CANCEL,
|
||||||
loader_style=ui.LDR_DANGER)
|
loader_style=ui.LDR_DANGER)
|
||||||
|
@ -30,9 +30,7 @@ async def get_address(ctx, msg):
|
|||||||
|
|
||||||
async def _show_address(ctx, address: str, network: int):
|
async def _show_address(ctx, address: str, network: int):
|
||||||
lines = split_address(address)
|
lines = split_address(address)
|
||||||
content = Text(
|
text = Text('Confirm address', ui.ICON_RECEIVE, icon_color=ui.GREEN)
|
||||||
'Confirm address', ui.ICON_RECEIVE,
|
text.type('%s network' % get_network_str(network))
|
||||||
ui.NORMAL, '%s network' % get_network_str(network),
|
text.mono(*lines)
|
||||||
ui.MONO, *lines,
|
return await confirm(ctx, text, code=ButtonRequestType.Address, cancel='QR', cancel_style=ui.BTN_KEY)
|
||||||
icon_color=ui.GREEN)
|
|
||||||
return await confirm(ctx, content, 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):
|
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)
|
await require_confirm(ctx, text, ButtonRequestType.ConfirmOutput)
|
||||||
|
|
||||||
|
|
||||||
async def require_confirm_final(ctx, fee: int):
|
async def require_confirm_final(ctx, fee: int):
|
||||||
content = Text(
|
text = Text('Final confirm', ui.ICON_SEND, icon_color=ui.GREEN)
|
||||||
'Final confirm', ui.ICON_SEND,
|
text.type('Sign this transaction')
|
||||||
ui.NORMAL, 'Sign this transaction',
|
text.bold('and pay %s XEM' % format_amount(fee, NEM_MAX_DIVISIBILITY))
|
||||||
ui.BOLD, 'and pay %s XEM' % format_amount(fee, NEM_MAX_DIVISIBILITY),
|
text.type('for network fee?')
|
||||||
ui.NORMAL, 'for network fee?',
|
|
||||||
icon_color=ui.GREEN)
|
|
||||||
# we use SignTx, not ConfirmOutput, for compatibility with T1
|
# 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):
|
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):
|
def _get_mosaic_properties(definition: NEMMosaicDefinition):
|
||||||
properties = []
|
properties = []
|
||||||
|
|
||||||
|
# description
|
||||||
if definition.description:
|
if definition.description:
|
||||||
t = Text('Confirm properties', ui.ICON_SEND,
|
t = Text('Confirm properties', ui.ICON_SEND)
|
||||||
ui.BOLD, 'Description:',
|
t.bold('Description:')
|
||||||
ui.NORMAL, *split_words(trim(definition.description, 70), 22))
|
t.type(*split_words(trim(definition.description, 70), 22))
|
||||||
properties.append(t)
|
properties.append(t)
|
||||||
|
|
||||||
|
# transferable
|
||||||
if definition.transferable:
|
if definition.transferable:
|
||||||
transferable = 'Yes'
|
transferable = 'Yes'
|
||||||
else:
|
else:
|
||||||
transferable = 'No'
|
transferable = 'No'
|
||||||
t = Text('Confirm properties', ui.ICON_SEND,
|
t = Text('Confirm properties', ui.ICON_SEND)
|
||||||
ui.BOLD, 'Transferable?',
|
t.bold('Transferable?')
|
||||||
ui.NORMAL, transferable)
|
t.type(transferable)
|
||||||
properties.append(t)
|
properties.append(t)
|
||||||
|
|
||||||
|
# mutable_supply
|
||||||
if definition.mutable_supply:
|
if definition.mutable_supply:
|
||||||
imm = 'mutable'
|
imm = 'mutable'
|
||||||
else:
|
else:
|
||||||
imm = 'immutable'
|
imm = 'immutable'
|
||||||
if definition.supply:
|
if definition.supply:
|
||||||
t = Text('Confirm properties', ui.ICON_SEND,
|
t = Text('Confirm properties', ui.ICON_SEND)
|
||||||
ui.BOLD, 'Initial supply:',
|
t.bold('Initial supply:')
|
||||||
ui.NORMAL, str(definition.supply),
|
t.type(str(definition.supply), imm)
|
||||||
ui.NORMAL, imm)
|
|
||||||
else:
|
else:
|
||||||
t = Text('Confirm properties', ui.ICON_SEND,
|
t = Text('Confirm properties', ui.ICON_SEND)
|
||||||
ui.BOLD, 'Initial supply:',
|
t.bold('Initial supply:')
|
||||||
ui.NORMAL, imm)
|
t.type(imm)
|
||||||
properties.append(t)
|
properties.append(t)
|
||||||
|
|
||||||
|
# levy
|
||||||
if definition.levy:
|
if definition.levy:
|
||||||
t = Text('Confirm properties', ui.ICON_SEND,
|
|
||||||
ui.BOLD, 'Levy recipient:',
|
t = Text('Confirm properties', ui.ICON_SEND)
|
||||||
ui.MONO, *split_address(definition.levy_address))
|
t.bold('Levy recipient:')
|
||||||
|
t.mono(*split_address(definition.levy_address))
|
||||||
properties.append(t)
|
properties.append(t)
|
||||||
t = Text('Confirm properties', ui.ICON_SEND,
|
|
||||||
ui.BOLD, 'Levy fee:',
|
t = Text('Confirm properties', ui.ICON_SEND)
|
||||||
ui.NORMAL, str(definition.fee),
|
t.bold('Levy fee:')
|
||||||
ui.BOLD, 'Levy divisibility:',
|
t.type(str(definition.fee))
|
||||||
ui.NORMAL, str(definition.divisibility))
|
t.bold('Levy divisibility:')
|
||||||
|
t.type(str(definition.divisibility))
|
||||||
properties.append(t)
|
properties.append(t)
|
||||||
t = Text('Confirm properties', ui.ICON_SEND,
|
|
||||||
ui.BOLD, 'Levy namespace:',
|
t = Text('Confirm properties', ui.ICON_SEND)
|
||||||
ui.NORMAL, definition.levy_namespace,
|
t.bold('Levy namespace:')
|
||||||
ui.BOLD, 'Levy mosaic:',
|
t.type(definition.levy_namespace)
|
||||||
ui.NORMAL, definition.levy_mosaic)
|
t.bold('Levy mosaic:')
|
||||||
|
t.type(definition.levy_mosaic)
|
||||||
properties.append(t)
|
properties.append(t)
|
||||||
|
|
||||||
if definition.levy == NEMMosaicLevy.MosaicLevy_Absolute:
|
if definition.levy == NEMMosaicLevy.MosaicLevy_Absolute:
|
||||||
levy_type = 'absolute'
|
levy_type = 'absolute'
|
||||||
else:
|
else:
|
||||||
levy_type = 'percentile'
|
levy_type = 'percentile'
|
||||||
t = Text('Confirm properties', ui.ICON_SEND,
|
t = Text('Confirm properties', ui.ICON_SEND)
|
||||||
ui.BOLD, 'Levy type:',
|
t.bold('Levy type:')
|
||||||
ui.NORMAL, levy_type)
|
t.type(levy_type)
|
||||||
properties.append(t)
|
properties.append(t)
|
||||||
|
|
||||||
return properties
|
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):
|
async def _require_confirm_address(ctx, action: str, address: str):
|
||||||
content = Text('Confirm address', ui.ICON_SEND,
|
text = Text('Confirm address', ui.ICON_SEND, icon_color=ui.GREEN)
|
||||||
ui.NORMAL, action,
|
text.type(action)
|
||||||
ui.MONO, *split_address(address),
|
text.mono(*split_address(address))
|
||||||
icon_color=ui.GREEN)
|
await require_confirm(ctx, text, ButtonRequestType.ConfirmOutput)
|
||||||
await require_confirm(ctx, content, 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
|
mosaic_quantity = mosaic.quantity * transfer.amount / NEM_MOSAIC_AMOUNT_DIVISOR
|
||||||
|
|
||||||
if definition:
|
if definition:
|
||||||
msg = Text('Confirm mosaic', ui.ICON_SEND,
|
msg = Text('Confirm mosaic', ui.ICON_SEND, icon_color=ui.GREEN)
|
||||||
'Confirm transfer of',
|
msg.type('Confirm transfer of')
|
||||||
ui.BOLD, format_amount(mosaic_quantity, definition['divisibility']) + definition['ticker'],
|
msg.bold(format_amount(mosaic_quantity, definition['divisibility']) + definition['ticker'])
|
||||||
ui.NORMAL, 'of',
|
msg.type('of')
|
||||||
ui.BOLD, definition['name'],
|
msg.bold(definition['name'])
|
||||||
icon_color=ui.GREEN)
|
|
||||||
|
|
||||||
await require_confirm(ctx, msg, ButtonRequestType.ConfirmOutput)
|
await require_confirm(ctx, msg, ButtonRequestType.ConfirmOutput)
|
||||||
|
|
||||||
if 'levy' in definition and 'fee' in definition:
|
if 'levy' in definition and 'fee' in definition:
|
||||||
levy_msg = _get_levy_msg(definition, mosaic_quantity, common.network)
|
levy_msg = _get_levy_msg(definition, mosaic_quantity, common.network)
|
||||||
msg = Text('Confirm mosaic', ui.ICON_SEND,
|
msg = Text('Confirm mosaic', ui.ICON_SEND, icon_color=ui.GREEN)
|
||||||
'Confirm mosaic',
|
msg.type('Confirm mosaic', 'levy fee of')
|
||||||
'levy fee of',
|
msg.bold(levy_msg)
|
||||||
ui.BOLD, levy_msg,
|
|
||||||
icon_color=ui.GREEN)
|
|
||||||
|
|
||||||
await require_confirm(ctx, msg, ButtonRequestType.ConfirmOutput)
|
await require_confirm(ctx, msg, ButtonRequestType.ConfirmOutput)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
msg = Text('Confirm mosaic', ui.ICON_SEND,
|
msg = Text('Confirm mosaic', ui.ICON_SEND, icon_color=ui.RED)
|
||||||
ui.BOLD, 'Unknown mosaic!',
|
msg.bold('Unknown mosaic!')
|
||||||
ui.NORMAL, *split_words('Divisibility and levy cannot be shown for unknown mosaics', 22),
|
msg.type(*split_words('Divisibility and levy cannot be shown for unknown mosaics', 22))
|
||||||
icon_color=ui.RED)
|
|
||||||
await require_confirm(ctx, msg, ButtonRequestType.ConfirmOutput)
|
await require_confirm(ctx, msg, ButtonRequestType.ConfirmOutput)
|
||||||
|
|
||||||
msg = Text('Confirm mosaic', ui.ICON_SEND,
|
msg = Text('Confirm mosaic', ui.ICON_SEND, icon_color=ui.GREEN)
|
||||||
ui.NORMAL, 'Confirm transfer of',
|
msg.type('Confirm transfer of')
|
||||||
ui.BOLD, '%s raw units' % mosaic_quantity,
|
msg.bold('%s raw units' % mosaic_quantity)
|
||||||
ui.NORMAL, 'of',
|
msg.type('of')
|
||||||
ui.BOLD, '%s.%s' % (mosaic.namespace, mosaic.mosaic),
|
msg.bold('%s.%s' % (mosaic.namespace, mosaic.mosaic))
|
||||||
icon_color=ui.GREEN)
|
|
||||||
await require_confirm(ctx, msg, ButtonRequestType.ConfirmOutput)
|
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):
|
async def _require_confirm_transfer(ctx, recipient, value):
|
||||||
content = Text('Confirm transfer', ui.ICON_SEND,
|
text = Text('Confirm transfer', ui.ICON_SEND, icon_color=ui.GREEN)
|
||||||
ui.BOLD, 'Send %s XEM' % format_amount(value, NEM_MAX_DIVISIBILITY),
|
text.bold('Send %s XEM' % format_amount(value, NEM_MAX_DIVISIBILITY))
|
||||||
ui.NORMAL, 'to',
|
text.type('to')
|
||||||
ui.MONO, *split_address(recipient),
|
text.mono(*split_address(recipient))
|
||||||
icon_color=ui.GREEN)
|
await require_confirm(ctx, text, ButtonRequestType.ConfirmOutput)
|
||||||
await require_confirm(ctx, content, ButtonRequestType.ConfirmOutput)
|
|
||||||
|
|
||||||
|
|
||||||
async def _require_confirm_payload(ctx, payload: bytes, encrypt=False):
|
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:
|
if len(payload) > 48:
|
||||||
payload = payload[:48] + '..'
|
payload = payload[:48] + '..'
|
||||||
if encrypt:
|
if encrypt:
|
||||||
content = Text('Confirm payload', ui.ICON_SEND,
|
text = Text('Confirm payload', ui.ICON_SEND, icon_color=ui.GREEN)
|
||||||
ui.BOLD, 'Encrypted:',
|
text.bold('Encrypted:')
|
||||||
ui.NORMAL, *split_words(payload, 22),
|
text.type(*split_words(payload, 22))
|
||||||
icon_color=ui.GREEN)
|
|
||||||
else:
|
else:
|
||||||
content = Text('Confirm payload', ui.ICON_SEND,
|
text = Text('Confirm payload', ui.ICON_SEND, icon_color=ui.RED)
|
||||||
ui.BOLD, 'Unencrypted:',
|
text.bold('Unencrypted:')
|
||||||
ui.NORMAL, *split_words(payload, 22),
|
text.type(*split_words(payload, 22))
|
||||||
icon_color=ui.RED)
|
await require_confirm(ctx, text, ButtonRequestType.ConfirmOutput)
|
||||||
await require_confirm(ctx, content, ButtonRequestType.ConfirmOutput)
|
|
||||||
|
@ -20,8 +20,9 @@ async def cipher_key_value(ctx, msg):
|
|||||||
title = 'Encrypt value'
|
title = 'Encrypt value'
|
||||||
else:
|
else:
|
||||||
title = 'Decrypt value'
|
title = 'Decrypt value'
|
||||||
lines = split_words(msg.key, ui.WIDTH - 2 * TEXT_MARGIN_LEFT, metric=lambda x: ui.display.text_width(x, ui.NORMAL))
|
text = Text(title, ui.ICON_DEFAULT)
|
||||||
await require_confirm(ctx, Text(title, ui.ICON_DEFAULT, max_lines=5, *lines))
|
text.type(msg.key)
|
||||||
|
await require_confirm(ctx, text)
|
||||||
|
|
||||||
node = await seed.derive_node(ctx, msg.address_n)
|
node = await seed.derive_node(ctx, msg.address_n)
|
||||||
value = compute_cipher_key_value(msg, node.private_key())
|
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):
|
async def require_confirm_ecdh_session_key(ctx, identity):
|
||||||
lines = chunks(serialize_identity_without_proto(identity), 18)
|
lines = chunks(serialize_identity_without_proto(identity), 18)
|
||||||
proto = identity.proto.upper() if identity.proto else 'identity'
|
proto = identity.proto.upper() if identity.proto else 'identity'
|
||||||
header = 'Decrypt %s' % (proto,)
|
text = Text('Decrypt %s' % proto, ui.ICON_DEFAULT)
|
||||||
content = Text(header, ui.ICON_DEFAULT, ui.MONO, *lines, max_lines=5)
|
text.mono(*lines)
|
||||||
await require_confirm(ctx, content)
|
await require_confirm(ctx, text)
|
||||||
|
|
||||||
|
|
||||||
def get_ecdh_path(identity: str, index: int):
|
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):
|
async def get_entropy(ctx, msg):
|
||||||
|
|
||||||
await require_confirm(ctx, Text(
|
text = Text('Confirm entropy', ui.ICON_DEFAULT)
|
||||||
'Confirm entropy', ui.ICON_DEFAULT,
|
text.bold('Do you really want', 'to send entropy?')
|
||||||
ui.BOLD, 'Do you really want', 'to send entropy?',
|
text.type('Continue only if you', 'know what you are doing!')
|
||||||
ui.NORMAL, 'Continue only if you', 'know what you are doing!'),
|
await require_confirm(ctx, text, code=ButtonRequestType.ProtectCall)
|
||||||
code=ButtonRequestType.ProtectCall)
|
|
||||||
|
|
||||||
size = min(msg.size, 1024)
|
size = min(msg.size, 1024)
|
||||||
entropy = random.bytes(size)
|
entropy = random.bytes(size)
|
||||||
|
@ -38,8 +38,9 @@ async def get_public_key(ctx, msg):
|
|||||||
|
|
||||||
async def _show_pubkey(ctx, pubkey: bytes):
|
async def _show_pubkey(ctx, pubkey: bytes):
|
||||||
lines = chunks(hexlify(pubkey).decode(), 18)
|
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(
|
return await require_confirm(
|
||||||
ctx,
|
ctx,
|
||||||
content,
|
text,
|
||||||
code=ButtonRequestType.PublicKey)
|
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))
|
lines.extend(chunks(serialize_identity_without_proto(identity), 18))
|
||||||
|
|
||||||
proto = identity.proto.upper() if identity.proto else 'identity'
|
proto = identity.proto.upper() if identity.proto else 'identity'
|
||||||
header = 'Sign %s' % proto
|
text = Text('Sign %s' % proto, ui.ICON_DEFAULT)
|
||||||
content = Text(header, ui.ICON_DEFAULT, *lines, max_lines=5)
|
text.type(*lines)
|
||||||
await require_confirm(ctx, content)
|
await require_confirm(ctx, text)
|
||||||
|
|
||||||
|
|
||||||
def serialize_identity(identity):
|
def serialize_identity(identity):
|
||||||
|
@ -39,5 +39,6 @@ async def sign_message(ctx, msg):
|
|||||||
|
|
||||||
async def require_confirm_sign_message(ctx, message):
|
async def require_confirm_sign_message(ctx, message):
|
||||||
message = split_message(message)
|
message = split_message(message)
|
||||||
content = Text('Sign message', ui.ICON_DEFAULT, max_lines=5, *message)
|
text = Text('Sign message', ui.ICON_DEFAULT)
|
||||||
await require_confirm(ctx, content)
|
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()
|
data = hexlify(output.op_return_data).decode()
|
||||||
if len(data) >= 18 * 5:
|
if len(data) >= 18 * 5:
|
||||||
data = data[:(18 * 5 - 3)] + '...'
|
data = data[:(18 * 5 - 3)] + '...'
|
||||||
content = Text('OP_RETURN', ui.ICON_SEND,
|
text = Text('OP_RETURN', ui.ICON_SEND, icon_color=ui.GREEN)
|
||||||
ui.MONO, *split_op_return(data), icon_color=ui.GREEN)
|
text.mono(*split_op_return(data))
|
||||||
else:
|
else:
|
||||||
address = output.address
|
address = output.address
|
||||||
address_short = addresses.address_short(coin, address)
|
address_short = addresses.address_short(coin, address)
|
||||||
content = Text('Confirm sending', ui.ICON_SEND,
|
text = Text('Confirm sending', ui.ICON_SEND, icon_color=ui.GREEN)
|
||||||
ui.NORMAL, format_coin_amount(output.amount, coin) + ' to',
|
text.type(format_coin_amount(output.amount, coin) + ' to')
|
||||||
ui.MONO, *split_address(address_short), icon_color=ui.GREEN)
|
text.mono(*split_address(address_short))
|
||||||
return await confirm(ctx, content, ButtonRequestType.ConfirmOutput)
|
return await confirm(ctx, text, ButtonRequestType.ConfirmOutput)
|
||||||
|
|
||||||
|
|
||||||
async def confirm_total(ctx, spending, fee, coin):
|
async def confirm_total(ctx, spending, fee, coin):
|
||||||
content = Text('Confirm transaction', ui.ICON_SEND,
|
text = Text('Confirm transaction', ui.ICON_SEND, icon_color=ui.GREEN)
|
||||||
'Total amount:',
|
text.type('Total amount:')
|
||||||
ui.BOLD, format_coin_amount(spending, coin),
|
text.bold(format_coin_amount(spending, coin))
|
||||||
ui.NORMAL, 'including fee:',
|
text.type('including fee:')
|
||||||
ui.BOLD, format_coin_amount(fee, coin), icon_color=ui.GREEN)
|
text.bold(format_coin_amount(fee, coin))
|
||||||
return await hold_to_confirm(ctx, content, ButtonRequestType.SignTx)
|
return await hold_to_confirm(ctx, text, ButtonRequestType.SignTx)
|
||||||
|
|
||||||
|
|
||||||
async def confirm_feeoverthreshold(ctx, fee, coin):
|
async def confirm_feeoverthreshold(ctx, fee, coin):
|
||||||
content = Text('High fee', ui.ICON_SEND,
|
text = Text('High fee', ui.ICON_SEND, icon_color=ui.GREEN)
|
||||||
'The fee of',
|
text.type('The fee of')
|
||||||
ui.BOLD, format_coin_amount(fee, coin),
|
text.bold(format_coin_amount(fee, coin))
|
||||||
ui.NORMAL, 'is unexpectedly high.',
|
text.type('is unexpectedly high.', 'Continue?')
|
||||||
'Continue?', icon_color=ui.GREEN)
|
return await confirm(ctx, text, ButtonRequestType.FeeOverThreshold)
|
||||||
|
|
||||||
return await confirm(ctx, content, ButtonRequestType.FeeOverThreshold)
|
|
||||||
|
|
||||||
|
|
||||||
async def confirm_foreign_address(ctx, address_n, coin):
|
async def confirm_foreign_address(ctx, address_n, coin):
|
||||||
content = Text('Confirm sending', ui.ICON_SEND,
|
text = Text('Confirm sending', ui.ICON_SEND, icon_color=ui.RED)
|
||||||
|
text.type(
|
||||||
'Trying to spend',
|
'Trying to spend',
|
||||||
'coins from another chain.',
|
'coins from another chain.',
|
||||||
'Continue?', icon_color=ui.RED)
|
'Continue?')
|
||||||
|
return await confirm(ctx, text, ButtonRequestType.SignTx)
|
||||||
return await confirm(ctx, content, ButtonRequestType.SignTx)
|
|
||||||
|
@ -57,10 +57,10 @@ async def verify_message(ctx, msg):
|
|||||||
|
|
||||||
|
|
||||||
async def require_confirm_verify_message(ctx, address, message):
|
async def require_confirm_verify_message(ctx, address, message):
|
||||||
lines = split_address(address)
|
text = Text('Confirm address', ui.ICON_DEFAULT)
|
||||||
content = Text('Confirm address', ui.ICON_DEFAULT, ui.MONO, *lines)
|
text.mono(*split_address(address))
|
||||||
await require_confirm(ctx, content)
|
await require_confirm(ctx, text)
|
||||||
|
|
||||||
message = split_message(message)
|
text = Text('Verify message', ui.ICON_DEFAULT)
|
||||||
content = Text('Verify message', ui.ICON_DEFAULT, max_lines=5, *message)
|
text.type(*split_message(message))
|
||||||
await require_confirm(ctx, content)
|
await require_confirm(ctx, text)
|
||||||
|
Loading…
Reference in New Issue
Block a user