async def confirm_output(ctx, output, coin): from trezor.ui.text import Text from apps.common.confirm import confirm from apps.wallet.sign_tx import addresses, omni if output.script_type == OutputScriptType.PAYTOOPRETURN: data = output.op_return_data if omni.is_valid(data): # OMNI transaction text = Text("OMNI transaction", ui.ICON_SEND, ui.GREEN) text.normal(omni.parse(data)) else: # generic OP_RETURN data = hexlify(data).decode() if len(data) >= 18 * 5: data = data[: (18 * 5 - 3)] + "..." text = Text("OP_RETURN", ui.ICON_SEND, ui.GREEN) text.mono(*split_op_return(data)) else: address = output.address address_short = addresses.address_short(coin, address) text = Text("Confirm sending", ui.ICON_SEND, ui.GREEN) text.normal(format_coin_amount(output.amount, coin) + " to") text.mono(*split_address(address_short)) return await confirm(ctx, text, ButtonRequestType.ConfirmOutput)
async def get_address(ctx, msg): coin_name = msg.coin_name or "Bitcoin" coin = coins.by_name(coin_name) node = await seed.derive_node(ctx, msg.address_n, curve_name=coin.curve_name) address = addresses.get_address(msg.script_type, coin, node, msg.multisig) address_short = addresses.address_short(coin, address) if msg.show_display: if msg.multisig: desc = "Multisig %d of %d" % (msg.multisig.m, len(msg.multisig.pubkeys)) else: desc = address_n_to_str(msg.address_n) while True: if await show_address(ctx, address_short, desc=desc): break if await show_qr( ctx, address.upper() if msg.script_type == InputScriptType.SPENDWITNESS else address, desc=desc, ): break return Address(address=address)
async def get_address(ctx, msg, keychain): coin_name = msg.coin_name or "Bitcoin" coin = coins.by_name(coin_name) await validate_path( ctx, addresses.validate_full_path, keychain, msg.address_n, coin.curve_name, coin=coin, script_type=msg.script_type, ) node = keychain.derive(msg.address_n, coin.curve_name) address = addresses.get_address(msg.script_type, coin, node, msg.multisig) address_short = addresses.address_short(coin, address) if msg.script_type == InputScriptType.SPENDWITNESS: address_qr = address.upper() # bech32 address else: address_qr = address # base58 address if msg.show_display: if msg.multisig: desc = "Multisig %d of %d" % (msg.multisig.m, len(msg.multisig.pubkeys)) else: desc = address_n_to_str(msg.address_n) while True: if await show_address(ctx, address_short, desc=desc): break if await show_qr(ctx, address_qr, desc=desc): break return Address(address=address)
async def confirm_output(ctx, output, coin): if output.script_type == OutputScriptType.PAYTOOPRETURN: 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) 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)
async def confirm_output(ctx, output, coin): if output.script_type == OutputScriptType.PAYTOOPRETURN: data = hexlify(output.op_return_data).decode() if len(data) >= 18 * 5: data = data[:(18 * 5 - 3)] + "..." 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) text = Text("Confirm sending", ui.ICON_SEND, icon_color=ui.GREEN) text.normal(format_coin_amount(output.amount, coin) + " to") text.mono(*split_address(address_short)) return await confirm(ctx, text, ButtonRequestType.ConfirmOutput)
async def get_address(ctx, msg, keychain): coin_name = msg.coin_name or "Bitcoin" coin = coins.by_name(coin_name) await validate_path( ctx, addresses.validate_full_path, keychain, msg.address_n, coin.curve_name, coin=coin, script_type=msg.script_type, ) node = keychain.derive(msg.address_n, coin.curve_name) address = addresses.get_address(msg.script_type, coin, node, msg.multisig) address_short = addresses.address_short(coin, address) if msg.script_type == InputScriptType.SPENDWITNESS: address_qr = address.upper() # bech32 address elif coin.cashaddr_prefix is not None: address_qr = address.upper() # cashaddr address else: address_qr = address # base58 address if msg.show_display: if msg.multisig: if msg.multisig.nodes: pubnodes = msg.multisig.nodes else: pubnodes = [hd.node for hd in msg.multisig.pubkeys] multisig_index = multisig_pubkey_index(msg.multisig, node.public_key()) desc = "Multisig %d of %d" % (msg.multisig.m, len(pubnodes)) while True: if await show_address(ctx, address_short, desc=desc): break if await show_qr(ctx, address_qr, desc=desc, cancel="XPUBs"): break if await show_xpubs(ctx, coin, pubnodes, multisig_index): break else: desc = address_n_to_str(msg.address_n) while True: if await show_address(ctx, address_short, desc=desc): break if await show_qr(ctx, address_qr, desc=desc): break return Address(address=address)
async def verify_message(ctx, msg): message = msg.message address = msg.address signature = msg.signature coin_name = msg.coin_name or "Bitcoin" coin = coins.by_name(coin_name) digest = message_digest(coin, message) script_type = None recid = signature[0] if recid >= 27 and recid <= 34: script_type = SPENDADDRESS # p2pkh elif recid >= 35 and recid <= 38: script_type = SPENDP2SHWITNESS # segwit-in-p2sh signature = bytes([signature[0] - 4]) + signature[1:] elif recid >= 39 and recid <= 42: script_type = SPENDWITNESS # native segwit signature = bytes([signature[0] - 8]) + signature[1:] else: raise wire.ProcessError("Invalid signature") pubkey = secp256k1.verify_recover(signature, digest) if not pubkey: raise wire.ProcessError("Invalid signature") if script_type == SPENDADDRESS: addr = address_pkh(pubkey, coin) if coin.cashaddr_prefix is not None: addr = address_to_cashaddr(addr, coin) elif script_type == SPENDP2SHWITNESS: addr = address_p2wpkh_in_p2sh(pubkey, coin) elif script_type == SPENDWITNESS: addr = address_p2wpkh(pubkey, coin.bech32_prefix) else: raise wire.ProcessError("Invalid signature") if addr != address: raise wire.ProcessError("Invalid signature") await require_confirm_verify_message(ctx, address_short(coin, address), message) return Success(message="Message verified")
async def get_address(ctx, msg): coin_name = msg.coin_name or 'Bitcoin' coin = coins.by_name(coin_name) node = await seed.derive_node(ctx, msg.address_n) address = addresses.get_address(msg.script_type, coin, node, msg.multisig) address_short = addresses.address_short(coin, address) if msg.show_display: while True: if await show_address(ctx, address_short): break if await show_qr( ctx, address.upper() if msg.script_type == InputScriptType.SPENDWITNESS else address): break return Address(address=address)