Show QR code when exploring addresses
This commit is contained in:
parent
69fdc4b805
commit
240fc65775
@ -9,6 +9,7 @@ import chains, stash
|
||||
from ux import ux_show_story, the_ux, ux_confirm
|
||||
from actions import goto_top_menu
|
||||
from menu import MenuSystem, MenuItem, start_chooser
|
||||
from public_constants import AFC_BECH32
|
||||
|
||||
SCREEN_CHAR_WIDTH = const(16)
|
||||
|
||||
@ -71,11 +72,13 @@ async def choose_first_address(*a):
|
||||
async def show_n_addresses(path, addr_fmt, start, n):
|
||||
# Displays n addresses from start
|
||||
from main import dis
|
||||
import version
|
||||
|
||||
def make_msg(start):
|
||||
msg = "Press 1 to save to MicroSD.\n\n"
|
||||
msg += "Addresses %d..%d:\n\n" % (start, start + n - 1)
|
||||
|
||||
addrs = []
|
||||
chain = chains.current_chain()
|
||||
|
||||
dis.fullscreen('Wait...')
|
||||
@ -85,38 +88,48 @@ async def show_n_addresses(path, addr_fmt, start, n):
|
||||
for idx in range(start, start + n):
|
||||
subpath = path.format(account=0, change=0, idx=idx)
|
||||
node = sv.derive_path(subpath, register=False)
|
||||
msg += "%s =>\n%s\n\n" % (subpath, chain.address(node, addr_fmt))
|
||||
addr = chain.address(node, addr_fmt)
|
||||
addrs.append(addr)
|
||||
|
||||
msg += "%s =>\n%s\n\n" % (subpath, addr)
|
||||
|
||||
dis.progress_bar_show(idx/n)
|
||||
|
||||
stash.blank_object(node)
|
||||
|
||||
if version.has_fatram:
|
||||
msg += "Press 4 to view QR Code. "
|
||||
|
||||
msg += "Press 9 to see next group, 7 to go back. X to quit."
|
||||
|
||||
return msg
|
||||
return msg, addrs
|
||||
|
||||
msg = make_msg(start)
|
||||
msg, addrs = make_msg(start)
|
||||
|
||||
while 1:
|
||||
ch = await ux_show_story(msg, escape='179')
|
||||
ch = await ux_show_story(msg, escape='1479')
|
||||
|
||||
if ch == '1':
|
||||
# save addresses to MicroSD signal
|
||||
await make_address_summary_file(path, addr_fmt)
|
||||
# .. continue on same screen in case they want to write to multiple cards
|
||||
if ch == '1':
|
||||
# save addresses to MicroSD signal
|
||||
await make_address_summary_file(path, addr_fmt)
|
||||
# .. continue on same screen in case they want to write to multiple cards
|
||||
|
||||
if ch == 'x':
|
||||
return
|
||||
if ch == 'x':
|
||||
return
|
||||
|
||||
if ch == '7' and start>0:
|
||||
# go backwards in explorer
|
||||
start -= n
|
||||
msg = make_msg(start)
|
||||
if ch == '4':
|
||||
if not version.has_fatram: continue
|
||||
await show_address_qr(addrs, (addr_fmt & AFC_BECH32), start)
|
||||
continue
|
||||
|
||||
if ch == '9':
|
||||
# go forwards
|
||||
start += n
|
||||
msg = make_msg(start)
|
||||
if ch == '7' and start>0:
|
||||
# go backwards in explorer
|
||||
start -= n
|
||||
elif ch == '9':
|
||||
# go forwards
|
||||
start += n
|
||||
|
||||
msg, addrs = make_msg(start)
|
||||
|
||||
def generate_address_csv(path, addr_fmt, n):
|
||||
# Produce CSV file contents as a generator
|
||||
@ -200,4 +213,106 @@ Press 4 to start.''', escape='4')
|
||||
|
||||
await show_n_addresses(path, addr_fmt, 0, 10)
|
||||
|
||||
|
||||
async def show_address_qr(addrs, is_segwit, start_n):
|
||||
# show a QR code for the address. can only work on Mk3
|
||||
# Version 2 would be nice, but can't hold what we need, even at min error correction,
|
||||
# so we are forced into version 3 = 29x29 pixels
|
||||
# - see <https://www.qrcode.com/en/about/version.html>
|
||||
# - to display 29x29 pixels, we have to double them up: 58x58
|
||||
# - not really providing enough space around it
|
||||
# - inverted QR (black/white swap) still readable by scanners, altho wrong
|
||||
|
||||
from utils import imported
|
||||
from display import FontSmall, FontTiny
|
||||
import uQR as uqr
|
||||
from main import dis
|
||||
|
||||
idx = 0 # start with first address
|
||||
invert = False # looks better, but neither mode is ideal
|
||||
|
||||
addr = addrs[idx]
|
||||
|
||||
def render(addr):
|
||||
dis.busy_bar(True)
|
||||
with imported('uQR') as uqr:
|
||||
if is_segwit:
|
||||
# targeting 'alpha numeric' mode, typical len is 42
|
||||
ec = uqr.ERROR_CORRECT_Q
|
||||
assert len(addr) <= 47
|
||||
else:
|
||||
# has to be 'binary' mode, altho shorter msg, typical 34-36
|
||||
ec = uqr.ERROR_CORRECT_M
|
||||
assert len(addr) <= 42
|
||||
|
||||
q = uqr.QRCode(version=3, box_size=1, border=0, mask_pattern=3, error_correction=ec)
|
||||
if is_segwit:
|
||||
here = uqr.QRData(addr.upper().encode('ascii'),
|
||||
mode=uqr.MODE_ALPHA_NUM, check_data=False)
|
||||
else:
|
||||
here = uqr.QRData(addr.encode('ascii'), mode=uqr.MODE_8BIT_BYTE, check_data=False)
|
||||
q.add_data(here)
|
||||
q.make(fit=False)
|
||||
|
||||
return q.get_matrix()
|
||||
|
||||
data = render(addr)
|
||||
|
||||
def redraw():
|
||||
dis.clear()
|
||||
|
||||
w = 29 # because version=3
|
||||
XO,YO = 7, 3 # offsets
|
||||
|
||||
if not invert:
|
||||
dis.dis.fill_rect(XO-YO, 0, 64, 64, 1)
|
||||
|
||||
for x in range(w):
|
||||
for y in range(w):
|
||||
px = data[x][y]
|
||||
X = (x*2) + XO
|
||||
Y = (y*2) + YO
|
||||
dis.dis.fill_rect(X,Y, 2,2, px if invert else (not px))
|
||||
|
||||
x, y = 73, 0 if is_segwit else 2
|
||||
ll = 7 # per line
|
||||
for i in range(0, len(addr), ll):
|
||||
dis.text(x, y, addr[i:i+ll], FontSmall)
|
||||
y += 10 if is_segwit else 12
|
||||
|
||||
if not invert:
|
||||
# show path number, very tiny
|
||||
ai = str(start_n + idx)
|
||||
if len(ai) == 1:
|
||||
dis.text(0, 30, ai[0], FontTiny)
|
||||
else:
|
||||
dis.text(0, 27, ai[0], FontTiny)
|
||||
dis.text(0, 27+7, ai[1], FontTiny)
|
||||
|
||||
dis.busy_bar(False) # includes show
|
||||
|
||||
redraw()
|
||||
|
||||
from ux import ux_wait_keyup
|
||||
|
||||
while 1:
|
||||
ch = await ux_wait_keyup()
|
||||
|
||||
if ch == '1':
|
||||
invert = not invert
|
||||
redraw()
|
||||
continue
|
||||
elif ch in 'xy':
|
||||
return
|
||||
if ch == '5' or ch == '7':
|
||||
if idx > 0:
|
||||
idx -= 1
|
||||
elif ch == '8' or ch == '9':
|
||||
if idx != len(addrs)-1:
|
||||
idx += 1
|
||||
|
||||
addr = addrs[idx]
|
||||
data = render(addr)
|
||||
redraw()
|
||||
|
||||
# EOF
|
||||
|
||||
@ -1,4 +1,7 @@
|
||||
# from https://github.com/JASchilz/uQR/blob/master/uQR.py @ 0d105634841368ef0b1bb210a63c48e4b50a9a94
|
||||
#
|
||||
# Please see <https://github.com/JASchilz/uQR/blob/master/LICENSE> for BSD-style license.
|
||||
#
|
||||
import ure as re
|
||||
|
||||
"""
|
||||
@ -17,10 +20,10 @@ Formerly in constants.py
|
||||
"""
|
||||
|
||||
# QR error correct levels
|
||||
ERROR_CORRECT_L = 1
|
||||
ERROR_CORRECT_M = 0
|
||||
ERROR_CORRECT_Q = 3
|
||||
ERROR_CORRECT_H = 2
|
||||
ERROR_CORRECT_L = const(1)
|
||||
ERROR_CORRECT_M = const(0)
|
||||
ERROR_CORRECT_Q = const(3)
|
||||
ERROR_CORRECT_H = const(2)
|
||||
|
||||
"""
|
||||
LUT
|
||||
@ -1022,7 +1025,7 @@ def create_data(version, error_correction, data_list):
|
||||
bit_limit += block.data_count * 8
|
||||
|
||||
if len(buffer) > bit_limit:
|
||||
raise exceptions.DataOverflowError(
|
||||
raise DataOverflowError(
|
||||
"Code length overflow. Data size (%s) > size available (%s)" %
|
||||
(len(buffer), bit_limit))
|
||||
|
||||
|
||||
@ -18,15 +18,17 @@ if '-s' in sys.argv:
|
||||
numpad.inject('4')
|
||||
numpad.inject('y')
|
||||
|
||||
if '-a' in sys.argv:
|
||||
if '--addr' in sys.argv:
|
||||
# Address Explorer
|
||||
from main import numpad
|
||||
numpad.inject('4')
|
||||
numpad.inject('y')
|
||||
numpad.inject('4')
|
||||
numpad.inject('8')
|
||||
numpad.inject('8')
|
||||
numpad.inject('y')
|
||||
numpad.inject('y')
|
||||
numpad.inject('4') # skips warning!
|
||||
|
||||
if '--dz' in sys.argv:
|
||||
# Enter the "Danger Zone"
|
||||
@ -36,6 +38,7 @@ if '--dz' in sys.argv:
|
||||
numpad.inject('4')
|
||||
numpad.inject('8')
|
||||
numpad.inject('8')
|
||||
numpad.inject('8')
|
||||
numpad.inject('y')
|
||||
|
||||
if '--xw' in sys.argv:
|
||||
|
||||
Loading…
Reference in New Issue
Block a user