1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2025-07-30 10:28:14 +00:00

feat(core): show Zcash non-standard paths via address_extra

This commit is contained in:
Tomas Krnak 2022-12-17 12:18:53 +07:00
parent f85e6a9a90
commit 4e8dcfff80

View File

@ -9,9 +9,9 @@ from trezor.ui.layouts import show_address
from apps.bitcoin import keychain as t_keychain
from apps.common import address_type
from apps.common.coininfo import CoinInfo, by_name
from apps.common.paths import HARDENED, address_n_to_str
from apps.common.paths import HARDENED, PATTERN_BIP44, PathSchema, address_n_to_str
from .orchard.keychain import OrchardKeychain
from .orchard.keychain import PATTERN_ZIP32, OrchardKeychain
from .unified import Typecode, encode_address
if TYPE_CHECKING:
@ -19,44 +19,55 @@ if TYPE_CHECKING:
from trezor.messages import ZcashGetAddress
ORCHARD = Typecode.ORCHARD
P2PKH = Typecode.P2PKH
def encode_p2pkh(raw_address: bytes, coin: CoinInfo) -> str:
return base58.encode_check(address_type.tobytes(coin.address_type) + raw_address)
async def get_address(ctx: Context, msg: ZcashGetAddress) -> ZcashAddress:
if not (msg.t_address_n or msg.z_address_n):
raise wire.DataError("t-address or z-address path expected")
coin = by_name(msg.coin_name)
address_extra = None
receivers = {}
if msg.z_address_n:
receivers = {}
receivers[Typecode.ORCHARD] = await get_raw_orchard_address(ctx, coin, msg)
if msg.t_address_n:
# this check only makes sense if paths match the respective patterns
# (i.e. t_address_n follows BIP-44 and z_address_n follows ZIP-32)
if msg.t_address_n[2] != msg.z_address_n[2]:
raise wire.DataError("Receivers use different account numbers.")
receivers[Typecode.P2PKH] = await get_raw_transparent_address(
ctx, coin, msg
)
receivers[ORCHARD] = await get_raw_orchard_address(ctx, coin, msg)
if msg.t_address_n:
receivers[P2PKH] = await get_raw_transparent_address(ctx, coin, msg)
if tuple(receivers.keys()) == (): # no receivers
raise wire.DataError("t-address or z-address path expected")
elif tuple(receivers.keys()) == (P2PKH,): # only transparent receiver
title = address_n_to_str(msg.t_address_n)
address = encode_p2pkh(receivers[P2PKH], coin)
elif tuple(receivers.keys()) == (ORCHARD,): # only shielded receiver
title = address_n_to_str(msg.z_address_n)
address = encode_address(receivers, coin)
elif ( # transparent + shielded, unified path
PathSchema.parse(PATTERN_BIP44, coin.slip44).match(msg.t_address_n) and
PathSchema.parse(PATTERN_ZIP32, coin.slip44).match(msg.z_address_n) and
msg.t_address_n[2] == msg.z_address_n[2]
):
title = "u/{coin_type}/{account}/{receivers}".format(
coin_type=msg.z_address_n[1] ^ HARDENED,
account=msg.z_address_n[2] ^ HARDENED,
receivers=",".join(map(str, receivers.keys())),
)
address = encode_address(receivers, coin)
else: # transparent + shielded, incompatible paths
title = "Unified address"
address_extra = "\n".join((
"Receivers:",
"- transparent",
address_n_to_str(msg.t_address_n),
"- Orchard",
address_n_to_str(msg.z_address_n),
))
address = encode_address(receivers, coin)
else: # has only t-address
title = address_n_to_str(msg.t_address_n)
raw_address = await get_raw_transparent_address(ctx, coin, msg)
address = encode_p2pkh(raw_address, coin)
if msg.show_display:
await show_address(ctx, address=address, address_qr=address, title=title)
await show_address(ctx, address=address, address_qr=address, title=title, address_extra=address_extra)
return ZcashAddress(address=address)