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

xmr: get_address - pagination, integrated address (#201)

xmr: get_address - pagination, integrated address
This commit is contained in:
Tomas Susanka 2019-05-31 15:06:46 +02:00 committed by GitHub
commit 6a27328801
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 65 additions and 4 deletions

View File

@ -81,6 +81,7 @@ message MoneroGetAddress {
optional uint32 network_type = 3; // Main-net / testnet / stagenet
optional uint32 account = 4; // Major subaddr index
optional uint32 minor = 5; // Minor subaddr index
optional bytes payment_id = 6; // Payment ID for integrated address
}
/**

View File

@ -1,8 +1,11 @@
from trezor.messages.MoneroAddress import MoneroAddress
from apps.common import paths
from apps.common.layout import address_n_to_str, show_address, show_qr
from apps.common.layout import address_n_to_str, show_qr
from apps.monero import CURVE, misc
from apps.monero.layout import confirms
from apps.monero.xmr import addresses, crypto, monero
from apps.monero.xmr.networks import net_version
async def get_address(ctx, msg, keychain):
@ -11,13 +14,38 @@ async def get_address(ctx, msg, keychain):
)
creds = misc.get_creds(keychain, msg.address_n, msg.network_type)
addr = creds.address
if msg.payment_id:
if len(msg.payment_id) != 8:
raise ValueError("Invalid payment ID length")
addr = addresses.encode_addr(
net_version(msg.network_type, False, True),
crypto.encodepoint(creds.spend_key_public),
crypto.encodepoint(creds.view_key_public),
msg.payment_id,
)
if msg.account or msg.minor:
if msg.payment_id:
raise ValueError("Subaddress cannot be integrated")
pub_spend, pub_view = monero.generate_sub_address_keys(
creds.view_key_private, creds.spend_key_public, msg.account, msg.minor
)
addr = addresses.encode_addr(
net_version(msg.network_type, True, False),
crypto.encodepoint(pub_spend),
crypto.encodepoint(pub_view),
)
if msg.show_display:
desc = address_n_to_str(msg.address_n)
while True:
if await show_address(ctx, creds.address.decode(), desc=desc):
if await confirms.show_address(ctx, addr.decode(), desc=desc):
break
if await show_qr(ctx, creds.address.decode(), desc=desc):
if await show_qr(ctx, "monero:" + addr.decode(), desc=desc):
break
return MoneroAddress(address=creds.address)
return MoneroAddress(address=addr)

View File

@ -41,6 +41,7 @@ async def naive_pagination(
def paginate_lines(lines, lines_per_page=5):
"""Paginates lines across pages with preserving formatting modifiers (e.g., mono)"""
pages = []
cpage = []
nlines = 0

View File

@ -194,3 +194,28 @@ async def live_refresh_step(ctx, current):
if current is None:
return
await Popup(LiveRefreshStep(current))
async def show_address(
ctx, address: str, desc: str = "Confirm address", network: str = None
):
from apps.common.confirm import confirm
from trezor.messages import ButtonRequestType
from trezor.ui.button import ButtonDefault
from trezor.ui.scroll import Paginated
pages = []
for lines in common.paginate_lines(common.split_address(address), 5):
text = Text(desc, ui.ICON_RECEIVE, ui.GREEN)
if network is not None:
text.normal("%s network" % network)
text.mono(*lines)
pages.append(text)
return await confirm(
ctx,
Paginated(pages),
code=ButtonRequestType.Address,
cancel="QR",
cancel_style=ButtonDefault,
)

View File

@ -19,12 +19,14 @@ class MoneroGetAddress(p.MessageType):
network_type: int = None,
account: int = None,
minor: int = None,
payment_id: bytes = None,
) -> None:
self.address_n = address_n if address_n is not None else []
self.show_display = show_display
self.network_type = network_type
self.account = account
self.minor = minor
self.payment_id = payment_id
@classmethod
def get_fields(cls):
@ -34,4 +36,5 @@ class MoneroGetAddress(p.MessageType):
3: ('network_type', p.UVarintType, 0),
4: ('account', p.UVarintType, 0),
5: ('minor', p.UVarintType, 0),
6: ('payment_id', p.BytesType, 0),
}

View File

@ -19,12 +19,14 @@ class MoneroGetAddress(p.MessageType):
network_type: int = None,
account: int = None,
minor: int = None,
payment_id: bytes = None,
) -> None:
self.address_n = address_n if address_n is not None else []
self.show_display = show_display
self.network_type = network_type
self.account = account
self.minor = minor
self.payment_id = payment_id
@classmethod
def get_fields(cls):
@ -34,4 +36,5 @@ class MoneroGetAddress(p.MessageType):
3: ('network_type', p.UVarintType, 0),
4: ('account', p.UVarintType, 0),
5: ('minor', p.UVarintType, 0),
6: ('payment_id', p.BytesType, 0),
}