1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-12-22 06:18:07 +00:00

feat(core): Implement GetAddress for taproot.

This commit is contained in:
Andrew Kozlik 2021-10-16 10:07:19 +02:00 committed by Andrew Kozlik
parent 6406f0640d
commit dd7ed61939
3 changed files with 21 additions and 1 deletions

View File

@ -0,0 +1 @@
Support GetAddress for Taproot addresses.

View File

@ -1,5 +1,6 @@
from trezor import wire from trezor import wire
from trezor.crypto import base58, cashaddr from trezor.crypto import base58, cashaddr
from trezor.crypto.curve import bip340
from trezor.crypto.hashlib import sha256 from trezor.crypto.hashlib import sha256
from trezor.enums import InputScriptType from trezor.enums import InputScriptType
from trezor.messages import MultisigRedeemScriptType from trezor.messages import MultisigRedeemScriptType
@ -56,6 +57,15 @@ def get_address(
# native p2wpkh # native p2wpkh
return address_p2wpkh(node.public_key(), coin) return address_p2wpkh(node.public_key(), coin)
elif script_type == InputScriptType.SPENDTAPROOT: # taproot
if not coin.taproot or not coin.bech32_prefix:
raise wire.ProcessError("Taproot not enabled on this coin")
if multisig is not None:
raise wire.ProcessError("Multisig not supported for taproot")
return address_p2tr(node.public_key(), coin)
elif ( elif (
script_type == InputScriptType.SPENDP2SHWITNESS script_type == InputScriptType.SPENDP2SHWITNESS
): # p2wpkh or p2wsh nested in p2sh ): # p2wpkh or p2wsh nested in p2sh
@ -130,6 +140,12 @@ def address_p2wsh(witness_script_hash: bytes, hrp: str) -> str:
return encode_bech32_address(hrp, 0, witness_script_hash) return encode_bech32_address(hrp, 0, witness_script_hash)
def address_p2tr(pubkey: bytes, coin: CoinInfo) -> str:
assert coin.bech32_prefix is not None
output_pubkey = bip340.tweak_public_key(pubkey[1:])
return encode_bech32_address(coin.bech32_prefix, 1, output_pubkey)
def address_to_cashaddr(address: str, coin: CoinInfo) -> str: def address_to_cashaddr(address: str, coin: CoinInfo) -> str:
assert coin.cashaddr_prefix is not None assert coin.cashaddr_prefix is not None
raw = base58.decode_check(address, coin.b58_hash) raw = base58.decode_check(address, coin.b58_hash)

View File

@ -52,7 +52,10 @@ async def get_address(
address = addresses.get_address(msg.script_type, coin, node, msg.multisig) address = addresses.get_address(msg.script_type, coin, node, msg.multisig)
address_short = addresses.address_short(coin, address) address_short = addresses.address_short(coin, address)
if coin.segwit and msg.script_type == InputScriptType.SPENDWITNESS: if coin.segwit and msg.script_type in (
InputScriptType.SPENDWITNESS,
InputScriptType.SPENDTAPROOT,
):
address_qr = address.upper() # bech32 address address_qr = address.upper() # bech32 address
elif coin.cashaddr_prefix is not None: elif coin.cashaddr_prefix is not None:
address_qr = address.upper() # cashaddr address address_qr = address.upper() # cashaddr address