unified multisig import
This commit is contained in:
parent
366670b4d5
commit
a3d5485fd2
@ -10,7 +10,7 @@ from ux import ux_enter_bip32_index, ux_enter_number, OK, X
|
||||
from files import CardSlot, CardMissingError, needs_microsd
|
||||
from descriptor import MultisigDescriptor, multisig_descriptor_template
|
||||
from public_constants import AF_P2SH, AF_P2WSH_P2SH, AF_P2WSH, AFC_SCRIPT, MAX_SIGNERS, AF_CLASSIC
|
||||
from menu import MenuSystem, MenuItem, NonDefaultMenuItem, start_chooser, ToggleMenuItem
|
||||
from menu import MenuSystem, MenuItem, NonDefaultMenuItem, start_chooser, ToggleMenuItem, ShortcutItem
|
||||
from opcodes import OP_CHECKMULTISIG
|
||||
from exceptions import FatalPSBTIssue
|
||||
from glob import settings
|
||||
@ -1380,7 +1380,7 @@ class MultisigMenu(MenuSystem):
|
||||
@classmethod
|
||||
def construct(cls):
|
||||
# Dynamic menu with user-defined names of wallets shown
|
||||
from glob import NFC
|
||||
from flow import nfc_enabled
|
||||
|
||||
if not MultisigWallet.exists():
|
||||
rv = [MenuItem('(none setup yet)', f=no_ms_yet)]
|
||||
@ -1390,11 +1390,7 @@ class MultisigMenu(MenuSystem):
|
||||
rv.append(MenuItem('%d/%d: %s' % (ms.M, ms.N, ms.name),
|
||||
menu=make_ms_wallet_menu, arg=ms.storage_idx))
|
||||
|
||||
rv.append(MenuItem('Import from File', f=import_multisig))
|
||||
rv.append(MenuItem('Import from QR', f=import_multisig_qr,
|
||||
predicate=version.has_qwerty, shortcut=KEY_QR))
|
||||
rv.append(MenuItem('Import via NFC', f=import_multisig_nfc,
|
||||
predicate=bool(NFC), shortcut=KEY_NFC))
|
||||
rv.append(MenuItem('Import', f=import_multisig))
|
||||
rv.append(MenuItem('Export XPUB', f=export_multisig_xpubs))
|
||||
rv.append(MenuItem('Create Airgapped', f=create_ms_step1))
|
||||
rv.append(MenuItem('Trust PSBT?', f=trust_psbt_menu))
|
||||
@ -1408,6 +1404,9 @@ class MultisigMenu(MenuSystem):
|
||||
rv.append(NonDefaultMenuItem(
|
||||
'Unsorted Multisig?' if version.has_qwerty else 'Unsorted Multi?',
|
||||
'unsort_ms', f=unsorted_ms_menu))
|
||||
|
||||
rv.append(ShortcutItem(KEY_NFC, predicate=nfc_enabled, f=import_multisig_nfc))
|
||||
rv.append(ShortcutItem(KEY_QR, predicate=version.has_qwerty, f=import_multisig_qr))
|
||||
return rv
|
||||
|
||||
def update_contents(self):
|
||||
@ -1913,26 +1912,19 @@ async def import_multisig_qr(*a):
|
||||
except Exception as e:
|
||||
await ux_show_story('Failed to import.\n\n%s\n%s' % (e, problem_file_line(e)))
|
||||
|
||||
|
||||
async def import_multisig(*a):
|
||||
# pick text file from SD card, import as multisig setup file
|
||||
from actions import file_picker
|
||||
from glob import VD
|
||||
from ux import import_export_prompt
|
||||
|
||||
force_vdisk = False
|
||||
if VD:
|
||||
prompt = "Press (1) to import multisig wallet file from SD Card"
|
||||
escape = "1"
|
||||
if VD is not None:
|
||||
prompt += ", press (2) to import from Virtual Disk"
|
||||
escape += "2"
|
||||
prompt += "."
|
||||
ch = await ux_show_story(prompt, escape=escape)
|
||||
if ch == "1":
|
||||
force_vdisk=False
|
||||
elif ch == "2":
|
||||
force_vdisk = True
|
||||
else:
|
||||
return
|
||||
ch = await import_export_prompt("multisig wallet file", is_import=True)
|
||||
if isinstance(ch, str):
|
||||
if ch == KEY_QR:
|
||||
await import_multisig_qr()
|
||||
elif ch == KEY_NFC:
|
||||
await import_multisig_nfc()
|
||||
return
|
||||
|
||||
def possible(filename):
|
||||
with open(filename, 'rt') as fd:
|
||||
@ -1944,11 +1936,11 @@ async def import_multisig(*a):
|
||||
return True
|
||||
|
||||
fn = await file_picker(suffix=['.txt', '.json'], min_size=100, max_size=20*200,
|
||||
taster=possible, force_vdisk=force_vdisk)
|
||||
taster=possible, **ch)
|
||||
if not fn: return
|
||||
|
||||
try:
|
||||
with CardSlot(force_vdisk=force_vdisk) as card:
|
||||
with CardSlot(**ch) as card:
|
||||
with open(fn, 'rt') as fp:
|
||||
data = fp.read()
|
||||
except CardMissingError:
|
||||
@ -1959,8 +1951,8 @@ async def import_multisig(*a):
|
||||
try:
|
||||
possible_name = (fn.split('/')[-1].split('.'))[0]
|
||||
maybe_enroll_xpub(config=data, name=possible_name)
|
||||
except Exception as e:
|
||||
#import sys; sys.print_exception(e)
|
||||
await ux_show_story('Failed to import.\n\n%s\n%s' % (e, problem_file_line(e)))
|
||||
except BaseException as e:
|
||||
# import sys; sys.print_exception(e)
|
||||
await ux_show_story('Failed to import multisig.\n\n%s\n%s' % (e, problem_file_line(e)))
|
||||
|
||||
# EOF
|
||||
|
||||
@ -1958,7 +1958,7 @@ def file_tx_signing_done(virtdisk_path, microsd_path):
|
||||
|
||||
txid = None
|
||||
for l in _split:
|
||||
if "TXID" in l:
|
||||
if "TXID:" in l:
|
||||
txid = l.split("\n")[-1].strip()
|
||||
assert len(txid) == 64, "wrong txid"
|
||||
break
|
||||
|
||||
@ -161,7 +161,7 @@ def offer_ms_import(cap_story, dev, sim_root_dir):
|
||||
return doit
|
||||
|
||||
@pytest.fixture
|
||||
def import_multisig(request, is_q1, need_keypress, offer_ms_import):
|
||||
def import_multisig(request, is_q1, need_keypress, offer_ms_import, press_nfc):
|
||||
def doit(fname=None, way="sd", data=None, name=None):
|
||||
assert fname or data
|
||||
if fname:
|
||||
@ -192,13 +192,15 @@ def import_multisig(request, is_q1, need_keypress, offer_ms_import):
|
||||
pick_menu_item("Multisig Wallets")
|
||||
time.sleep(.1)
|
||||
|
||||
ms_menu = cap_menu()
|
||||
pick_menu_item("Import")
|
||||
time.sleep(.1)
|
||||
title, story = cap_story()
|
||||
if way == "qr":
|
||||
if "Import from QR" not in ms_menu and not is_q1:
|
||||
if "to scan QR code" not in story and not is_q1:
|
||||
pytest.skip("No QR support")
|
||||
|
||||
scan_a_qr = request.getfixturevalue('scan_a_qr')
|
||||
pick_menu_item("Import from QR")
|
||||
need_keypress(KEY_QR)
|
||||
|
||||
actual_vers, parts = split_qrs(config, 'U', max_version=20)
|
||||
random.shuffle(parts)
|
||||
@ -208,11 +210,11 @@ def import_multisig(request, is_q1, need_keypress, offer_ms_import):
|
||||
time.sleep(2.0 / len(parts))
|
||||
|
||||
elif way == "nfc":
|
||||
if "Import via NFC" not in ms_menu:
|
||||
if "import via NFC" not in story:
|
||||
pytest.skip("NFC disabled")
|
||||
|
||||
nfc_write_text = request.getfixturevalue('nfc_write_text')
|
||||
pick_menu_item("Import via NFC")
|
||||
press_nfc()
|
||||
nfc_write_text(config)
|
||||
time.sleep(0.5)
|
||||
|
||||
@ -228,9 +230,6 @@ def import_multisig(request, is_q1, need_keypress, offer_ms_import):
|
||||
with open(path_f(fname), "w") as f:
|
||||
f.write(config)
|
||||
|
||||
pick_menu_item("Import from File")
|
||||
time.sleep(.1)
|
||||
_, story = cap_story()
|
||||
if way == "vdisk":
|
||||
if "(2) to import from Virtual Disk" not in story:
|
||||
pytest.skip("VDisk disabled")
|
||||
@ -862,7 +861,7 @@ def test_import_ux(N, vdisk, goto_home, cap_story, pick_menu_item,
|
||||
goto_home()
|
||||
pick_menu_item('Settings')
|
||||
pick_menu_item('Multisig Wallets')
|
||||
pick_menu_item('Import from File')
|
||||
pick_menu_item('Import')
|
||||
time.sleep(0.5)
|
||||
_, story = cap_story()
|
||||
if vdisk:
|
||||
@ -1735,7 +1734,7 @@ def test_make_airgapped(addr_fmt, acct_num, M_N, goto_home, cap_story, pick_menu
|
||||
goto_home()
|
||||
pick_menu_item('Settings')
|
||||
pick_menu_item('Multisig Wallets')
|
||||
pick_menu_item('Import from File')
|
||||
pick_menu_item('Import')
|
||||
time.sleep(0.5)
|
||||
_, story = cap_story()
|
||||
if "Press (1) to import multisig wallet file from SD Card" in story:
|
||||
@ -2573,7 +2572,7 @@ def test_legacy_multisig_witness_utxo_in_psbt(bitcoind, use_regtest, clear_ms, m
|
||||
goto_home()
|
||||
pick_menu_item('Settings')
|
||||
pick_menu_item('Multisig Wallets')
|
||||
pick_menu_item('Import from File')
|
||||
pick_menu_item('Import')
|
||||
time.sleep(0.3)
|
||||
_, story = cap_story()
|
||||
if "Press (1) to import multisig wallet file from SD Card" in story:
|
||||
@ -3065,7 +3064,7 @@ def test_exotic_descriptors(desc, clear_ms, goto_home, need_keypress, pick_menu_
|
||||
goto_home()
|
||||
pick_menu_item('Settings')
|
||||
pick_menu_item('Multisig Wallets')
|
||||
pick_menu_item('Import from File')
|
||||
pick_menu_item('Import')
|
||||
time.sleep(0.1)
|
||||
_, story = cap_story()
|
||||
if "Press (1) to import multisig wallet file from SD Card" in story:
|
||||
@ -3336,7 +3335,8 @@ def test_scan_any_qr(fpath, is_q1, scan_a_qr, clear_ms, goto_home,
|
||||
|
||||
@pytest.mark.parametrize("N", [3, 15])
|
||||
def test_bare_cc_ms_qr_import(N, make_multisig, scan_a_qr, clear_ms, goto_home,
|
||||
pick_menu_item, cap_story, press_cancel, is_q1):
|
||||
pick_menu_item, cap_story, press_cancel, is_q1,
|
||||
need_keypress):
|
||||
# bare:
|
||||
# - no fingerprints
|
||||
# - no xfps
|
||||
@ -3368,7 +3368,9 @@ def test_bare_cc_ms_qr_import(N, make_multisig, scan_a_qr, clear_ms, goto_home,
|
||||
# multisig import path needs to be used
|
||||
pick_menu_item("Settings")
|
||||
pick_menu_item("Multisig Wallets")
|
||||
pick_menu_item("Import from QR")
|
||||
pick_menu_item("Import")
|
||||
need_keypress(KEY_QR)
|
||||
|
||||
for p in parts:
|
||||
scan_a_qr(p)
|
||||
time.sleep(2.0 / len(parts))
|
||||
|
||||
Loading…
Reference in New Issue
Block a user