async def confirm_set_options_op(ctx, op: StellarSetOptionsOp): if op.inflation_destination_account: text = Text("Confirm operation", ui.ICON_CONFIRM, icon_color=ui.GREEN) text.bold("Set Inflation Destination") text.mono(*split(op.inflation_destination_account)) await require_confirm(ctx, text, ButtonRequestType.ConfirmOutput) if op.clear_flags: t = _format_flags(op.clear_flags) text = Text("Confirm operation", ui.ICON_CONFIRM, icon_color=ui.GREEN) text.bold("Clear Flags") text.mono(*t) await require_confirm(ctx, text, ButtonRequestType.ConfirmOutput) if op.set_flags: t = _format_flags(op.set_flags) text = Text("Confirm operation", ui.ICON_CONFIRM, icon_color=ui.GREEN) text.bold("Set Flags") text.mono(*t) await require_confirm(ctx, text, ButtonRequestType.ConfirmOutput) thresholds = _format_thresholds(op) if thresholds: text = Text("Confirm operation", ui.ICON_CONFIRM, icon_color=ui.GREEN) text.bold("Account Thresholds") text.mono(*thresholds) await require_confirm(ctx, text, ButtonRequestType.ConfirmOutput) if op.home_domain: text = Text("Confirm operation", ui.ICON_CONFIRM, icon_color=ui.GREEN) text.bold("Home Domain") text.mono(*split(op.home_domain)) await require_confirm(ctx, text, ButtonRequestType.ConfirmOutput) if op.signer_type is not None: if op.signer_weight > 0: t = "Add Signer (%s)" else: t = "Remove Signer (%s)" if op.signer_type == consts.SIGN_TYPE_ACCOUNT: text = Text("Confirm operation", ui.ICON_CONFIRM, icon_color=ui.GREEN) text.bold(t % "acc") text.mono(*split(helpers.address_from_public_key(op.signer_key))) await require_confirm(ctx, text, ButtonRequestType.ConfirmOutput) elif op.signer_type in (consts.SIGN_TYPE_PRE_AUTH, consts.SIGN_TYPE_HASH): if op.signer_type == consts.SIGN_TYPE_PRE_AUTH: signer_type = "auth" else: signer_type = "hash" text = Text("Confirm operation", ui.ICON_CONFIRM, icon_color=ui.GREEN) text.bold(t % signer_type) text.mono(*split(hexlify(op.signer_key).decode())) await require_confirm(ctx, text, ButtonRequestType.ConfirmOutput) else: raise ProcessError("Stellar: invalid signer type")
async def require_confirm_tx(ctx, to, value, chain_id, token=None, tx_type=None): if to: to_str = _ethereum_address_hex(to, networks.by_chain_id(chain_id)) else: 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.normal("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_change_display_rotation(ctx, rotation): if rotation == 0: label = "north" elif rotation == 90: label = "east" elif rotation == 180: label = "south" elif rotation == 270: label = "west" else: raise wire.DataError("Unsupported display rotation") text = Text("Change rotation", ui.ICON_CONFIG, new_lines=False) text.normal("Do you really want to", "change display rotation") text.normal("to") text.bold("%s?" % label) await require_confirm(ctx, text, ButtonRequestType.ProtectCall)
async def load_device(ctx, msg): if storage.is_initialized(): raise wire.UnexpectedMessage("Already initialized") if msg.node is not None: raise wire.ProcessError("LoadDevice.node is not supported") if not msg.mnemonics: raise wire.ProcessError("No mnemonic provided") word_count = len(msg.mnemonics[0].split(" ")) for m in msg.mnemonics[1:]: if word_count != len(m.split(" ")): raise wire.ProcessError( "All shares are required to have the same number of words") mnemonic_type = mnemonic.type_from_word_count(word_count) if (mnemonic_type == mnemonic.TYPE_BIP39 and not msg.skip_checksum and not bip39.check(msg.mnemonics[0])): raise wire.ProcessError("Mnemonic is not valid") text = Text("Loading seed") text.bold("Loading private seed", "is not recommended.") text.normal("Continue only if you", "know what you are doing!") await require_confirm(ctx, text) if mnemonic_type == mnemonic.TYPE_BIP39: secret = msg.mnemonics[0].encode() elif mnemonic_type == mnemonic.TYPE_SLIP39: identifier, iteration_exponent, secret = slip39.combine_mnemonics( msg.mnemonics) storage.device.set_slip39_identifier(identifier) storage.device.set_slip39_iteration_exponent(iteration_exponent) else: raise RuntimeError("Unknown mnemonic type") storage.device.store_mnemonic_secret(secret, mnemonic_type, needs_backup=True, no_backup=False) storage.device.load_settings(use_passphrase=msg.passphrase_protection, label=msg.label) if msg.pin: config.change_pin(pin_to_int(""), pin_to_int(msg.pin)) return Success(message="Device loaded")
async def show_qr(ctx, address: str, desc: str = None): qr_x = const(120) qr_y = const(115) qr_coef = const(4) qr = Qr(address, (qr_x, qr_y), qr_coef) text = Text(desc if desc else "Confirm address", ui.ICON_RECEIVE, icon_color=ui.GREEN) content = Container(qr, text) return await confirm( ctx, content, code=ButtonRequestType.Address, cancel="Address", cancel_style=ui.BTN_KEY, )
async def show_qr( ctx: wire.Context, address: str, desc: str = "Confirm address" ) -> bool: QR_X = const(120) QR_Y = const(115) QR_COEF = const(4) qr = Qr(address, QR_X, QR_Y, QR_COEF) text = Text(desc, ui.ICON_RECEIVE, ui.GREEN) content = Container(qr, text) return await confirm( ctx, content, code=ButtonRequestType.Address, cancel="Address", cancel_style=ButtonDefault, )
async def cipher_key_value(ctx, msg): if len(msg.value) % 16 > 0: raise wire.DataError('Value length must be a multiple of 16') encrypt = msg.encrypt decrypt = not msg.encrypt if (encrypt and msg.ask_on_encrypt) or (decrypt and msg.ask_on_decrypt): if encrypt: 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)) node = await seed.derive_node(ctx, msg.address_n) value = compute_cipher_key_value(msg, node.private_key()) return CipheredKeyValue(value=value)
async def wipe_device(ctx, msg): text = Text("Wipe device", ui.ICON_WIPE, icon_color=ui.RED) text.normal("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, ) storage.wipe() return Success(message="Device wiped")
async def confirm_layout(self) -> None: from trezor.ui.confirm import Confirm, CONFIRMED from trezor.ui.text import Text app_id = bytes( self.app_id) # could be bytearray, which doesn't have __hash__ if app_id == _BOGUS_APPID and self.action == _CONFIRM_REGISTER: text = Text("U2F", ui.ICON_WRONG, ui.RED) text.normal("Another U2F device", "was used to register", "in this application.") dialog = Confirm(text) else: content = ConfirmContent(self.action, app_id) dialog = Confirm(content) self.confirmed = await dialog is CONFIRMED
async def show_success( ctx: wire.Context, content: List[str], subheader: str = None, button: str = "Continue", ) -> None: text = Text("Success", ui.ICON_CONFIRM, ui.GREEN) if subheader: text.bold(subheader) text.br_half() for row in content: text.normal(row) await require_confirm(ctx, text, ButtonRequestType.Success, confirm=button, cancel=None)
async def show_warning( ctx: wire.Context, content: List[str], subheader: str = None, button: str = "Continue", ) -> None: text = Text("Warning", ui.ICON_WRONG, ui.RED) if subheader: text.bold(subheader) text.br_half() for row in content: text.normal(row) await require_confirm(ctx, text, ButtonRequestType.Warning, confirm=button, cancel=None)
async def require_confirm_fee(ctx, spending, gas_price, gas_limit, chain_id, token=None, tx_type=None): text = Text("Confirm transaction", ui.ICON_SEND, icon_color=ui.GREEN, new_lines=False) text.bold(format_ethereum_amount(spending, token, chain_id, tx_type)) text.normal(ui.GREY, "Gas price:", ui.FG) text.bold(format_ethereum_amount(gas_price, None, chain_id, tx_type)) text.normal(ui.GREY, "Maximum fee:", ui.FG) text.bold( format_ethereum_amount(gas_price * gas_limit, None, chain_id, tx_type)) await require_hold_to_confirm(ctx, text, ButtonRequestType.SignTx)
async def show_warning( ctx: wire.GenericContext, content: Iterable[str], subheader: Iterable[str] = [], button: str = "Try again", ) -> None: text = Text("Warning", ui.ICON_WRONG, ui.RED) if subheader: for row in subheader: text.bold(row) text.br_half() for row in content: text.normal(row) await require_confirm(ctx, text, ButtonRequestType.Warning, confirm=button, cancel=None)
async def confirm_layout(self) -> None: from trezor.ui.confirm import ConfirmDialog, CONFIRMED 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.render() await loop.sleep(3 * 1000 * 1000) self.confirmed = True else: content = ConfirmContent(self.action, self.app_id) dialog = ConfirmDialog(content, ) self.confirmed = await dialog == CONFIRMED
async def cipher_key_value(ctx, msg): if len(msg.value) % 16 > 0: raise wire.DataError("Value length must be a multiple of 16") encrypt = msg.encrypt decrypt = not msg.encrypt if (encrypt and msg.ask_on_encrypt) or (decrypt and msg.ask_on_decrypt): if encrypt: title = "Encrypt value" else: title = "Decrypt value" text = Text(title) text.normal(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()) return CipheredKeyValue(value=value)
async def require_confirm_tx(ctx, to_bytes, value, chain_id, token=None, tx_type=None): if to_bytes: to_str = address_from_bytes(to_bytes, networks.by_chain_id(chain_id)) else: to_str = "new contract?" text = Text("Confirm sending", ui.ICON_SEND, ui.GREEN, new_lines=False) text.bold(format_ethereum_amount(value, token, chain_id, tx_type)) text.normal(ui.GREY, "to", ui.FG) for to_line in split_address(to_str): text.br() text.mono(to_line) # we use SignTx, not ConfirmOutput, for compatibility with T1 await require_confirm(ctx, text, ButtonRequestType.SignTx)
async def show_reset_device_warning(ctx, use_slip39: bool): text = Text("Create new wallet", ui.ICON_RESET, new_lines=False) if use_slip39: text.bold("Create a new wallet") text.br() text.bold("with Shamir Backup?") else: text.bold("Do you want to create") text.br() text.bold("a new wallet?") text.br() text.br_half() text.normal("By continuing you agree") text.br() text.normal("to") text.bold("https://trezor.io/tos") await require_confirm(ctx, text, ButtonRequestType.ResetDevice, major_confirm=True) await LoadingAnimation()
async def respond_Pong(ctx, msg): from trezor.messages.Success import Success s = Success() s.message = msg.message if msg.button_protection: from apps.common.confirm import require_confirm from trezor.messages.ButtonRequestType import ProtectCall from trezor.ui.text import Text from trezor import ui await require_confirm(ctx, Text('Confirm', ui.ICON_RESET), ProtectCall) if msg.passphrase_protection: from apps.common.request_passphrase import protect_by_passphrase await protect_by_passphrase(ctx) return s
async def _show_qr(ctx, address): from trezor.messages.ButtonRequestType import Address from trezor.ui.text import Text from trezor.ui.qr import Qr from trezor.ui.container import Container from ..common.confirm import confirm qr_x = const(120) qr_y = const(115) qr_coef = const(4) content = Container(Qr(address, (qr_x, qr_y), qr_coef), Text('Confirm address', ui.ICON_RESET, ui.MONO)) return await confirm(ctx, content, code=Address, cancel='Address', cancel_style=ui.BTN_KEY)
async def confirm_backup(ctx): text = Text("Back up wallet", ui.ICON_RESET, new_lines=False) text.bold("New wallet created") text.br() text.bold("successfully!") text.br() text.br_half() text.normal("You should back up your") text.br() text.normal("new wallet right now.") return await confirm( ctx, text, ButtonRequestType.ResetDevice, cancel="Skip", confirm="Back up", major_confirm=True, )
async def confirm_backup_again(ctx): text = Text("Back up wallet", ui.ICON_RESET, new_lines=False) text.bold("Are you sure you want") text.br() text.bold("to skip the backup?") text.br() text.br_half() text.normal("You can back up your") text.br() text.normal("Trezor once, at any time.") return await confirm( ctx, text, ButtonRequestType.ResetDevice, cancel="Skip", confirm="Back up", major_confirm=True, )
async def show_address( ctx: wire.Context, address: str, desc: str = "Confirm address", cancel: str = "QR", network: str = None, ) -> bool: text = Text(desc, ui.ICON_RECEIVE, ui.GREEN) if network is not None: text.normal("%s network" % network) text.mono(*split_address(address)) return await confirm( ctx, text, code=ButtonRequestType.Address, cancel=cancel, cancel_style=ButtonDefault, )
async def wipe_device(ctx, msg): await 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), code=ButtonRequestType.WipeDevice, button_style=ui.BTN_CANCEL, loader_style=ui.LDR_DANGER) storage.wipe() return Success(message='Device wiped')
async def _insert_card_dialog(ctx: Optional[wire.Context]) -> None: text = Text("SD card protection", ui.ICON_WRONG) text.bold("SD card required.") text.br_half() if SD_CARD_HOT_SWAPPABLE: text.normal("Please insert your", "SD card.") btn_confirm = "Retry" # type: Optional[str] btn_cancel = "Abort" else: text.normal("Please unplug the", "device and insert your", "SD card.") btn_confirm = None btn_cancel = "Close" if ctx is None: if await Confirm(text, confirm=btn_confirm, cancel=btn_cancel) is not CONFIRMED: raise SdProtectCancelled else: if not await confirm(ctx, text, confirm=btn_confirm, cancel=btn_cancel): raise wire.ProcessError("SD card required.")
async def show_backup_warning(ctx, slip39=False): text = Text("Caution", ui.ICON_NOCOPY) if slip39: text.normal( "Never make a digital", "copy of your recovery", "shares and never upload", "them online!", ) else: text.normal( "Never make a digital", "copy of your recovery", "seed and never upload", "it online!", ) await require_confirm( ctx, text, ButtonRequestType.ResetDevice, "I understand", cancel=None )
async def show_mnemonic_page(page, page_count, mnemonic): from trezor.ui.button import Button from trezor.ui.text import Text from trezor.ui.scroll import Scrollpage, animate_swipe lines = ['%d. %s' % (wi + 1, word) for wi, word in mnemonic[page]] scroll_page = Scrollpage( Text('Recovery seed setup', ui.ICON_RESET, ui.MONO, lines), page, page_count) ui.display.clear() scroll_page.render() if page + 1 == page_count: await Button(ui.grid(4, n_x=1), "I'm done", normal_style=ui.BTN_CONFIRM, active_style=ui.BTN_CONFIRM_ACTIVE) ui.display.clear() else: await animate_swipe()
async def confirm_modify_fee( ctx: wire.Context, user_fee_change: int, total_fee_new: int, coin: CoinInfo, amount_unit: EnumTypeAmountUnit, ) -> None: text = Text("Fee modification", ui.ICON_SEND, ui.GREEN) if user_fee_change == 0: text.normal("Your fee did not change.") else: if user_fee_change < 0: text.normal("Decrease your fee by:") else: text.normal("Increase your fee by:") text.bold(format_coin_amount(abs(user_fee_change), coin, amount_unit)) text.br_half() text.normal("Transaction fee:") text.bold(format_coin_amount(total_fee_new, coin, amount_unit)) await require_hold_to_confirm(ctx, text, ButtonRequestType.SignTx)
async def transaction_step(state, step, sub_step=None): info = [] if step == 0: info = ["Signing..."] elif step == 100: info = [ "Processing inputs", "%d/%d" % (sub_step + 1, state.input_count) ] elif step == 200: info = ["Sorting..."] elif step == 300: info = ["Hashing inputs", "%d/%d" % (sub_step + 1, state.input_count)] elif step == 350: info = ["Processing..."] elif step == 400: info = [ "Processing outputs", "%d/%d" % (sub_step + 1, state.output_count) ] elif step == 500: info = ["Postprocessing..."] elif step == 600: info = ["Signing inputs", "%d/%d" % (sub_step + 1, state.input_count)] else: info = ["Processing..."] state.progress_cur += 1 ui.display.clear() text = Text("Signing transaction", ui.ICON_SEND, icon_color=ui.BLUE) text.render() p = 1000 * state.progress_cur // state.progress_total ui.display.loader(p, False, -4, ui.WHITE, ui.BG) ui.display.text_center(ui.WIDTH // 2, 210, info[0], ui.NORMAL, ui.FG, ui.BG) if len(info) > 1: ui.display.text_center(ui.WIDTH // 2, 235, info[1], ui.NORMAL, ui.FG, ui.BG) ui.display.refresh()
async def confirm_sending( ctx: wire.Context, ada_amount: int, token_bundle: List[CardanoAssetGroupType], to: str, ) -> None: for token_group in token_bundle: await confirm_sending_token_group(ctx, token_group) page1 = Text("Confirm transaction", ui.ICON_SEND, ui.GREEN) page1.normal("Confirm sending:") page1.bold(format_coin_amount(ada_amount)) page1.normal("to") to_lines = list(chunks(to, 17)) page1.bold(to_lines[0]) pages = [page1] + _paginate_lines(to_lines, 1, "Confirm transaction", ui.ICON_SEND) await require_confirm(ctx, Paginated(pages))
async def show_text_page( page: int, page_count: int, pages: list, title: str, icon=ui.ICON_RESET, icon_color=ui.ORANGE, ): if page_count == 1: page = 0 lines = pages[page] content = Text(title, icon, icon_color=icon_color) content.mono(*lines) content = Scrollpage(content, page, page_count) if page + 1 >= page_count: return await ConfirmDialog(content) else: content.render() await animate_swipe()