show descriptor & key expression in story; signed key expression export
This commit is contained in:
parent
45542d1d4f
commit
cfc46b565e
@ -1198,8 +1198,8 @@ async def ss_descriptor_skeleton(_0, _1, item):
|
||||
|
||||
async def key_expression_skeleton_step2(_1, _2, item):
|
||||
# pick a semi-random file name, render and save it.
|
||||
orig_path = item.arg
|
||||
await make_key_expression_export(orig_path)
|
||||
orig_path, addr_fmt = item.arg
|
||||
await make_key_expression_export(orig_path, addr_fmt)
|
||||
|
||||
async def key_expression_skeleton(_0, _1, item):
|
||||
# Export key expression -> [xfp/d/e/r]xpub
|
||||
@ -1212,12 +1212,14 @@ async def key_expression_skeleton(_0, _1, item):
|
||||
elif ch != 'y':
|
||||
return
|
||||
|
||||
# element on 2nd index is address format for signed exports
|
||||
# if multisig key use p2pkh
|
||||
todo = [
|
||||
("Segwit P2WPKH", "m/84h/%dh/%dh"),
|
||||
("Classic P2PKH", "m/44h/%dh/%dh"),
|
||||
("P2SH-Segwit", "m/49h/%dh/%dh"),
|
||||
("Multi P2WSH", "m/48h/%dh/%dh/2h"),
|
||||
("Multi P2SH-P2WSH", "m/48h/%dh/%dh/1h"),
|
||||
("Segwit P2WPKH", "m/84h/%dh/%dh", AF_P2WPKH),
|
||||
("Classic P2PKH", "m/44h/%dh/%dh", AF_CLASSIC),
|
||||
("P2SH-Segwit", "m/49h/%dh/%dh", AF_P2WPKH_P2SH),
|
||||
("Multi P2WSH", "m/48h/%dh/%dh/2h", AF_CLASSIC),
|
||||
("Multi P2SH-P2WSH", "m/48h/%dh/%dh/1h", AF_CLASSIC),
|
||||
]
|
||||
|
||||
from address_explorer import KeypathMenu
|
||||
@ -1228,8 +1230,8 @@ async def key_expression_skeleton(_0, _1, item):
|
||||
ct = chains.current_chain().b44_cointype
|
||||
|
||||
rv = [
|
||||
MenuItem(label, f=key_expression_skeleton_step2, arg=orig_der % (ct, acct_num))
|
||||
for label, orig_der in todo
|
||||
MenuItem(label, f=key_expression_skeleton_step2, arg=(orig_der % (ct, acct_num), af))
|
||||
for label, orig_der, af in todo
|
||||
]
|
||||
rv += [MenuItem("Custom Path", menu=doit)]
|
||||
|
||||
|
||||
@ -35,7 +35,8 @@ async def export_by_qr(body, label, type_code, force_bbqr=False):
|
||||
|
||||
|
||||
async def export_contents(title, contents, fname_pattern, derive=None, addr_fmt=None,
|
||||
is_json=False, force_bbqr=False, force_prompt=False, direct_way=None):
|
||||
is_json=False, force_bbqr=False, force_prompt=False, direct_way=None,
|
||||
intro="", footer="", ux_title=None):
|
||||
# export text and json files while offering NFC, QR & Vdisk
|
||||
# produces signed export in case of SD/Vdisk (signed with key at deriv and addr_fmt)
|
||||
# checks if suitable to offer QR export on Mk4
|
||||
@ -59,8 +60,8 @@ async def export_contents(title, contents, fname_pattern, derive=None, addr_fmt=
|
||||
ch = direct_way # set it to direct way only once, outside the loop
|
||||
while True:
|
||||
if direct_way is None:
|
||||
ch = await import_export_prompt("%s file" % title,
|
||||
force_prompt=force_prompt, no_qr=no_qr)
|
||||
ch = await import_export_prompt("%s file" % title, intro=intro, footnotes=footer,
|
||||
force_prompt=force_prompt, no_qr=no_qr, title=ux_title)
|
||||
if ch == KEY_CANCEL:
|
||||
break
|
||||
elif ch == KEY_QR:
|
||||
@ -500,11 +501,15 @@ async def make_descriptor_wallet_export(addr_type, account_num=0, mode=None, int
|
||||
)
|
||||
|
||||
dis.progress_bar_show(1)
|
||||
await export_contents("Descriptor", body, fname_pattern, derive + "/0/0",
|
||||
addr_type, force_prompt=True, direct_way=direct_way)
|
||||
|
||||
intro, footer = (body, "") if version.has_qwerty else ("", body)
|
||||
title = "Descriptor"
|
||||
await export_contents(title, body, fname_pattern, derive + "/0/0", addr_type,
|
||||
force_prompt=True, direct_way=direct_way, intro=intro, footer=footer,
|
||||
ux_title=title if version.has_qwerty else None)
|
||||
|
||||
|
||||
async def make_key_expression_export(orig_der, fname_pattern="key_expr.txt"):
|
||||
async def make_key_expression_export(orig_der, addr_fmt=AF_CLASSIC, fname_pattern="key_expr.txt"):
|
||||
from glob import dis
|
||||
|
||||
dis.fullscreen('Generating...')
|
||||
@ -516,8 +521,11 @@ async def make_key_expression_export(orig_der, fname_pattern="key_expr.txt"):
|
||||
|
||||
body = "[%s/%s]%s" % (xfp, orig_der.replace("m/", ""), ek)
|
||||
|
||||
await export_contents("Key Expression", body, fname_pattern,
|
||||
None, None, force_prompt=True)
|
||||
intro, footer = (body, "") if version.has_qwerty else ("", body)
|
||||
title = "Key Expression"
|
||||
await export_contents(title, body, fname_pattern, orig_der + "/0/0", addr_fmt,
|
||||
force_prompt=True, intro=intro, footer=footer,
|
||||
ux_title=title if version.has_qwerty else None)
|
||||
|
||||
# EOF
|
||||
|
||||
|
||||
@ -643,7 +643,7 @@ def test_export_xpub(chain, acct_num, dev, cap_menu, pick_menu_item, goto_home,
|
||||
def test_generic_descriptor_export(chain, addr_fmt, acct_num, goto_home,
|
||||
settings_set, need_keypress, expect_acctnum_captured, OK,
|
||||
pick_menu_item, way, cap_story, cap_menu, int_ext, settings_get,
|
||||
virtdisk_path, load_export, press_select, skip_if_useless_way):
|
||||
virtdisk_path, load_export, press_select, skip_if_useless_way, is_q1):
|
||||
|
||||
skip_if_useless_way(way)
|
||||
|
||||
@ -697,9 +697,16 @@ def test_generic_descriptor_export(chain, addr_fmt, acct_num, goto_home,
|
||||
|
||||
expect_acctnum_captured(acct_num)
|
||||
|
||||
time.sleep(.1)
|
||||
title, story = cap_story()
|
||||
idx = 0 if is_q1 else 1
|
||||
story_desc = story.split("\n\n")[idx]
|
||||
|
||||
contents = load_export(way, label="Descriptor", is_json=False, addr_fmt=addr_fmt)
|
||||
descriptor = contents.strip()
|
||||
|
||||
assert descriptor == story_desc.strip()
|
||||
|
||||
if int_ext is False:
|
||||
descriptor = descriptor.split("\n")[0] # external
|
||||
assert descriptor.startswith(desc_prefix)
|
||||
@ -771,6 +778,8 @@ def test_zeus_descriptor_export(addr_fmt, acct_num, goto_home, need_keypress, pi
|
||||
|
||||
time.sleep(.1)
|
||||
title, story = cap_story()
|
||||
idx = 0 if is_q1 else 1
|
||||
story_desc = story.split("\n\n")[idx]
|
||||
|
||||
expect_acctnum_captured(acct_num)
|
||||
|
||||
@ -789,6 +798,8 @@ def test_zeus_descriptor_export(addr_fmt, acct_num, goto_home, need_keypress, pi
|
||||
|
||||
descriptor = contents.strip()
|
||||
|
||||
assert descriptor == story_desc.strip()
|
||||
|
||||
assert descriptor.startswith(desc_prefix)
|
||||
desc_obj = Descriptor.parse(descriptor)
|
||||
assert desc_obj.serialize(int_ext=True) == descriptor
|
||||
@ -895,7 +906,7 @@ def test_samourai_vs_generic(chain, account, settings_set, pick_menu_item, goto_
|
||||
@pytest.mark.parametrize("acct_num", [None, (2 ** 31) - 1])
|
||||
def test_key_expression_export(chain, addr_fmt, acct_num, goto_home, settings_set, need_keypress,
|
||||
pick_menu_item, way, cap_story, cap_menu, virtdisk_path, dev,
|
||||
load_export, press_select, skip_if_useless_way):
|
||||
load_export, press_select, skip_if_useless_way, is_q1):
|
||||
|
||||
skip_if_useless_way(way, allow_mk4_qr=True)
|
||||
|
||||
@ -934,15 +945,22 @@ def test_key_expression_export(chain, addr_fmt, acct_num, goto_home, settings_se
|
||||
elif addr_fmt == AF_P2WSH:
|
||||
menu_item = "Multi P2WSH"
|
||||
derive = f"m/48h/{chain_num}h/{acct_num}h/2h"
|
||||
addr_fmt = AF_CLASSIC
|
||||
else:
|
||||
assert addr_fmt == AF_P2WSH_P2SH
|
||||
menu_item = "Multi P2SH-P2WSH"
|
||||
derive = f"m/48h/{chain_num}h/{acct_num}h/1h"
|
||||
addr_fmt = AF_CLASSIC
|
||||
|
||||
assert menu_item in menu
|
||||
pick_menu_item(menu_item)
|
||||
|
||||
contents = load_export(way, label="Key Expression", is_json=False, sig_check=False)
|
||||
time.sleep(.1)
|
||||
title, story = cap_story()
|
||||
idx = 0 if is_q1 else 1
|
||||
story_key_exp = story.split("\n\n")[idx]
|
||||
|
||||
contents = load_export(way, label="Key Expression", is_json=False,addr_fmt=addr_fmt)
|
||||
key_exp = contents.strip()
|
||||
|
||||
xfp = dev.master_fingerprint
|
||||
@ -954,7 +972,7 @@ def test_key_expression_export(chain, addr_fmt, acct_num, goto_home, settings_se
|
||||
).subkey_for_path(derive)
|
||||
|
||||
target = f"[{xfp}/{derive.replace('m/', '')}]{node.hwif()}"
|
||||
assert key_exp == target
|
||||
assert key_exp == target == story_key_exp
|
||||
|
||||
|
||||
@pytest.mark.parametrize('path', [
|
||||
@ -965,7 +983,7 @@ def test_key_expression_export(chain, addr_fmt, acct_num, goto_home, settings_se
|
||||
"m/45h",
|
||||
])
|
||||
def test_custom_key_expression_export(path, goto_home, pick_menu_item, cap_menu, need_keypress,
|
||||
press_select, load_export, use_testnet, dev):
|
||||
press_select, load_export, use_testnet, dev, cap_story, is_q1):
|
||||
use_testnet()
|
||||
goto_home()
|
||||
pick_menu_item("Advanced/Tools")
|
||||
@ -1003,7 +1021,12 @@ def test_custom_key_expression_export(path, goto_home, pick_menu_item, cap_menu,
|
||||
m = cap_menu()
|
||||
pick_menu_item(m[2 if part[-1] == "h" else 3])
|
||||
|
||||
contents = load_export("sd", label="Key Expression", is_json=False, sig_check=False)
|
||||
time.sleep(.25)
|
||||
title, story = cap_story()
|
||||
idx = 0 if is_q1 else 1
|
||||
story_key_exp = story.split("\n\n")[idx]
|
||||
|
||||
contents = load_export("sd", label="Key Expression", is_json=False)
|
||||
key_exp = contents.strip()
|
||||
|
||||
xfp = dev.master_fingerprint
|
||||
@ -1013,6 +1036,6 @@ def test_custom_key_expression_export(path, goto_home, pick_menu_item, cap_menu,
|
||||
node = BIP32Node.from_master_secret(seed, netcode="XTN").subkey_for_path(path)
|
||||
|
||||
target = f"[{xfp}/{path.replace('m/', '')}]{node.hwif()}"
|
||||
assert key_exp == target
|
||||
assert key_exp == target == story_key_exp
|
||||
|
||||
# EOF
|
||||
|
||||
Loading…
Reference in New Issue
Block a user