1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2025-01-03 03:50:58 +00:00

core: show xpubs in GetAddress for multisig

also fix not showing MultisigRedeemScriptType.nodes correctly
This commit is contained in:
Pavol Rusnak 2019-10-23 17:02:19 +00:00
parent c3d13f41a4
commit 9a3d8ef2c4
No known key found for this signature in database
GPG Key ID: 91F3B339B9A02A3D
2 changed files with 73 additions and 13 deletions

View File

@ -6,6 +6,7 @@ from trezor.messages import ButtonRequestType
from trezor.ui.button import ButtonDefault from trezor.ui.button import ButtonDefault
from trezor.ui.container import Container from trezor.ui.container import Container
from trezor.ui.qr import Qr from trezor.ui.qr import Qr
from trezor.ui.scroll import Paginated
from trezor.ui.text import Text from trezor.ui.text import Text
from trezor.utils import chunks from trezor.utils import chunks
@ -13,12 +14,16 @@ from apps.common import HARDENED
from apps.common.confirm import confirm, require_confirm from apps.common.confirm import confirm, require_confirm
if False: if False:
from typing import Iterable, Iterator from typing import Iterable, Iterator, List
from trezor import wire from trezor import wire
async def show_address( async def show_address(
ctx: wire.Context, address: str, desc: str = "Confirm address", network: str = None ctx: wire.Context,
address: str,
desc: str = "Confirm address",
cancel: str = "QR",
network: str = None,
) -> bool: ) -> bool:
text = Text(desc, ui.ICON_RECEIVE, ui.GREEN) text = Text(desc, ui.ICON_RECEIVE, ui.GREEN)
if network is not None: if network is not None:
@ -29,13 +34,16 @@ async def show_address(
ctx, ctx,
text, text,
code=ButtonRequestType.Address, code=ButtonRequestType.Address,
cancel="QR", cancel=cancel,
cancel_style=ButtonDefault, cancel_style=ButtonDefault,
) )
async def show_qr( async def show_qr(
ctx: wire.Context, address: str, desc: str = "Confirm address" ctx: wire.Context,
address: str,
desc: str = "Confirm address",
cancel: str = "Address",
) -> bool: ) -> bool:
QR_X = const(120) QR_X = const(120)
QR_Y = const(115) QR_Y = const(115)
@ -48,7 +56,7 @@ async def show_qr(
ctx, ctx,
content, content,
code=ButtonRequestType.Address, code=ButtonRequestType.Address,
cancel="Address", cancel=cancel,
cancel_style=ButtonDefault, cancel_style=ButtonDefault,
) )
@ -60,6 +68,22 @@ async def show_pubkey(ctx: wire.Context, pubkey: bytes) -> None:
await require_confirm(ctx, text, ButtonRequestType.PublicKey) await require_confirm(ctx, text, ButtonRequestType.PublicKey)
async def show_xpub(ctx: wire.Context, xpub: str, desc: str, cancel: str) -> bool:
pages = [] # type: List[ui.Component]
for lines in chunks(list(chunks(xpub, 16)), 5):
text = Text(desc, ui.ICON_RECEIVE, ui.GREEN)
text.mono(*lines)
pages.append(text)
return await confirm(
ctx,
Paginated(pages),
code=ButtonRequestType.PublicKey,
cancel=cancel,
cancel_style=ButtonDefault,
)
def split_address(address: str) -> Iterator[str]: def split_address(address: str) -> Iterator[str]:
return chunks(address, 17) return chunks(address, 17)

View File

@ -1,11 +1,37 @@
from trezor.crypto import bip32
from trezor.messages import InputScriptType from trezor.messages import InputScriptType
from trezor.messages.Address import Address from trezor.messages.Address import Address
from apps.common import coins from apps.common import coins
from apps.common.layout import address_n_to_str, show_address, show_qr from apps.common.layout import address_n_to_str, show_address, show_qr, show_xpub
from apps.common.paths import validate_path from apps.common.paths import validate_path
from apps.wallet.sign_tx import addresses from apps.wallet.sign_tx import addresses
if False:
from typing import List
from trezor.messages import HDNodeType
from trezor import wire
from apps.common.coininfo import CoinInfo
async def show_xpubs(
ctx: wire.Context, coin: CoinInfo, pubnodes: List[HDNodeType]
) -> bool:
for i, x in enumerate(pubnodes):
cancel = "Next" if i < len(pubnodes) - 1 else "Address"
node = bip32.HDNode(
depth=x.depth,
fingerprint=x.fingerprint,
child_num=x.child_num,
chain_code=x.chain_code,
public_key=x.public_key,
curve_name=coin.curve_name,
)
xpub = node.serialize_public(coin.xpub_magic)
if await show_xpub(ctx, xpub, desc="XPUB #%d" % (i + 1), cancel=cancel):
return True
return False
async def get_address(ctx, msg, keychain): async def get_address(ctx, msg, keychain):
coin_name = msg.coin_name or "Bitcoin" coin_name = msg.coin_name or "Bitcoin"
@ -33,14 +59,24 @@ async def get_address(ctx, msg, keychain):
if msg.show_display: if msg.show_display:
if msg.multisig: if msg.multisig:
desc = "Multisig %d of %d" % (msg.multisig.m, len(msg.multisig.pubkeys)) if msg.multisig.nodes:
pubnodes = msg.multisig.nodes
else:
pubnodes = [hd.node for hd in msg.multisig.pubkeys]
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):
break
else: else:
desc = address_n_to_str(msg.address_n) desc = address_n_to_str(msg.address_n)
while True:
while True: if await show_address(ctx, address_short, desc=desc):
if await show_address(ctx, address_short, desc=desc): break
break if await show_qr(ctx, address_qr, desc=desc):
if await show_qr(ctx, address_qr, desc=desc): break
break
return Address(address=address) return Address(address=address)