a lot more fixes
This commit is contained in:
parent
6eb1ef272d
commit
f70b05ba6f
@ -419,7 +419,7 @@ def generate_address_csv(path, addr_fmt, ms_wallet, account_num, n, start=0, cha
|
||||
saver = None
|
||||
|
||||
yield '"Index","Payment Address","Derivation"\n'
|
||||
for (idx, addr, deriv) in main.yield_addresses(start, n, change_idx=change):
|
||||
for (idx, addr, deriv) in main.yield_addresses(start, n, change):
|
||||
if saver:
|
||||
saver(addr)
|
||||
|
||||
|
||||
@ -1408,11 +1408,11 @@ class NewMiniscriptEnrollRequest(UserAuthorizedAction):
|
||||
if self.bsms_index is not None:
|
||||
# bsms special case, get him back to multisig menu
|
||||
from ux import the_ux, restore_menu
|
||||
from multisig import MultisigMenu
|
||||
from wallet import MiniscriptMenu
|
||||
while 1:
|
||||
top = the_ux.top_of_stack()
|
||||
if not top: break
|
||||
if not isinstance(top, MultisigMenu):
|
||||
if not isinstance(top, MiniscriptMenu):
|
||||
the_ux.pop()
|
||||
continue
|
||||
break
|
||||
|
||||
@ -300,7 +300,7 @@ async def restore_tmp_from_dict_ll(vals):
|
||||
if not k[:8] == "setting.":
|
||||
continue
|
||||
key = k[8:]
|
||||
if key in ["multisig", "miniscript"]:
|
||||
if key == "miniscript":
|
||||
# whitelist
|
||||
settings.set(key, v)
|
||||
|
||||
|
||||
@ -387,7 +387,9 @@ class Key:
|
||||
# new firmware, prefer key expression
|
||||
return cls.from_string(vals[key_exp])
|
||||
|
||||
ek = chains.slip32_deserialize(vals[af_str])
|
||||
# TODO
|
||||
node, _, _, _ = chains.slip32_deserialize(vals[af_str])
|
||||
ek = chains.current_chain().serialize_public(node)
|
||||
return cls.from_cc_data(vals["xfp"], vals["%s_deriv" % af_str], ek)
|
||||
|
||||
@classmethod
|
||||
|
||||
@ -142,22 +142,30 @@ async def ms_coordinator_file(af_str, my_xfp, slot_b=None):
|
||||
try:
|
||||
# CC multisig XPUBs JSON expected
|
||||
vals = ujson.load(fp)
|
||||
print("vals", vals)
|
||||
except:
|
||||
# try looking for BIP-380 key expression
|
||||
fp.seek(0)
|
||||
for line in fp.readlines():
|
||||
print(line)
|
||||
if len(line) > 112 and ("pub" in line):
|
||||
vals = line.strip()
|
||||
break
|
||||
|
||||
if isinstance(vals, dict):
|
||||
k = Key.from_cc_json(vals, af_str)
|
||||
else:
|
||||
k = Key.from_string(vals)
|
||||
print("here")
|
||||
try:
|
||||
if isinstance(vals, dict):
|
||||
k = Key.from_cc_json(vals, af_str)
|
||||
else:
|
||||
k = Key.from_string(vals)
|
||||
except Exception as e:
|
||||
sys.print_exception(e)
|
||||
raise
|
||||
|
||||
print("here1")
|
||||
num_mine += k.validate(my_xfp)
|
||||
keys.append(k)
|
||||
|
||||
print("here3")
|
||||
num_files += 1
|
||||
|
||||
except CardMissingError:
|
||||
@ -216,6 +224,8 @@ async def ondevice_multisig_create(mode='p2wsh', addr_fmt=AF_P2WSH, is_qr=False,
|
||||
# remove dups; easy to happen if you double-tap the export
|
||||
keys = list(set(keys))
|
||||
|
||||
print("keys", keys)
|
||||
|
||||
if not keys or (len(keys) == 1 and num_mine):
|
||||
if is_qr:
|
||||
msg = "No XPUBs scanned. Exit."
|
||||
|
||||
@ -32,8 +32,8 @@ from utils import call_later_ms
|
||||
# batt_to = (when on battery only) idle timeout period
|
||||
# _age = internal verison number for data (see below)
|
||||
# tested = selftest has been completed successfully
|
||||
# multisig = list of defined multisig wallets (complex)
|
||||
# miniscript = list of defined miniscript wallets (complex)
|
||||
# multisig = list of defined multisig wallets (complex) [before removal of MultisigWallet]
|
||||
# miniscript = list of defined miniscript wallets, including multisig (complex)
|
||||
# pms = trust/import/distrust xpubs found in PSBT files
|
||||
# fee_limit = (int) percentage of tx value allowed as max fee
|
||||
# axi = index of last selected address in explorer
|
||||
@ -79,7 +79,7 @@ from utils import call_later_ms
|
||||
# terms_ok = customer has signed-off on the terms of sale
|
||||
|
||||
# settings linked to seed
|
||||
# LINKED_SETTINGS = ["multisig","miniscript", "tp", "ovc", "xfp", "xpub", "words"]
|
||||
# LINKED_SETTINGS = ["miniscript", "tp", "ovc", "xfp", "xpub", "words"]
|
||||
# settings that does not make sense to copy to temporary secret
|
||||
# LINKED_SETTINGS += ["sd2fa", "usr", "axi", "hsmcmd"]
|
||||
# prelogin settings - do not need to be part of other saved settings
|
||||
|
||||
@ -211,6 +211,8 @@ class OwnershipCache:
|
||||
from wallet import MiniScriptWallet
|
||||
from glob import dis
|
||||
|
||||
print("addr", addr)
|
||||
|
||||
ch = chains.current_chain()
|
||||
|
||||
addr_fmt = ch.possible_address_fmt(addr)
|
||||
@ -257,6 +259,9 @@ class OwnershipCache:
|
||||
|
||||
# "quick" check first, before doing any generations
|
||||
|
||||
print()
|
||||
print(possibles)
|
||||
print()
|
||||
count = 0
|
||||
phase2 = []
|
||||
for change_idx in (0, 1):
|
||||
|
||||
128
shared/psbt.py
128
shared/psbt.py
@ -10,9 +10,10 @@ from utils import seconds2human_readable, datetime_from_timestamp, datetime_to_s
|
||||
from chains import NLOCK_IS_TIME
|
||||
from uhashlib import sha256
|
||||
from uio import BytesIO
|
||||
from charcodes import KEY_ENTER
|
||||
from sffile import SizerFile
|
||||
from chains import taptweak, tapleaf_hash
|
||||
from wallet import MiniScriptWallet
|
||||
from wallet import MiniScriptWallet, TRUST_PSBT, TRUST_VERIFY
|
||||
from multisig import disassemble_multisig_mn
|
||||
from exceptions import FatalPSBTIssue, FraudulentChangeOutput
|
||||
from serializations import ser_compact_size, deser_compact_size, hash160
|
||||
@ -561,12 +562,12 @@ class psbtOutputProxy(psbtProxy):
|
||||
|
||||
else:
|
||||
if active_miniscript:
|
||||
# TODO disable checks
|
||||
# if MultisigWallet.disable_checks:
|
||||
# # Without validation, we have to assume all outputs
|
||||
# # will be taken from us, and are not really change.
|
||||
# self.is_change = False
|
||||
# return af
|
||||
if MiniScriptWallet.disable_checks:
|
||||
# Without validation, we have to assume all outputs
|
||||
# will be taken from us, and are not really change.
|
||||
self.is_change = False
|
||||
return af
|
||||
|
||||
# scriptPubkey can be compared against script that we build - if exact match change
|
||||
# if not - not change - no need for redeem/witness script
|
||||
#
|
||||
@ -997,7 +998,8 @@ class psbtInputProxy(psbtProxy):
|
||||
|
||||
xfp_paths.sort()
|
||||
if psbt.active_miniscript:
|
||||
psbt.active_miniscript.matching_subpaths(xfp_paths), "wrong wallet"
|
||||
if not psbt.active_miniscript.disable_checks:
|
||||
psbt.active_miniscript.matching_subpaths(xfp_paths), "wrong wallet"
|
||||
else:
|
||||
# if we do have actual script at hand, guess M/N for better matching
|
||||
# basic multisig matching
|
||||
@ -1011,8 +1013,9 @@ class psbtInputProxy(psbtProxy):
|
||||
|
||||
try:
|
||||
# contains PSBT merkle root verification (if taproot)
|
||||
psbt.active_miniscript.validate_script_pubkey(utxo.scriptPubKey,
|
||||
xfp_paths, merkle_root)
|
||||
if not psbt.active_miniscript.disable_checks:
|
||||
psbt.active_miniscript.validate_script_pubkey(utxo.scriptPubKey,
|
||||
xfp_paths, merkle_root)
|
||||
except BaseException as e:
|
||||
# sys.print_exception(e)
|
||||
raise FatalPSBTIssue('Input #%d: %s\n\n' % (my_idx, e) + problem_file_line(e))
|
||||
@ -1408,34 +1411,42 @@ class psbtObject(psbtProxy):
|
||||
# Peek at the inputs to see if we can guess M/N value. Just takes
|
||||
# first one it finds.
|
||||
#
|
||||
for i in self.inputs:
|
||||
for idx, inp in self.input_iter():
|
||||
i = self.inputs[idx]
|
||||
ks = i.witness_script or i.redeem_script
|
||||
if not ks: continue
|
||||
|
||||
# guess address format also - based on scripts provided by PSBT provider
|
||||
if i.witness_script and not i.redeem_script:
|
||||
af = AF_P2WSH
|
||||
elif i.witness_script and i.redeem_script:
|
||||
af = AF_P2WSH_P2SH
|
||||
else:
|
||||
af = AF_P2SH
|
||||
|
||||
rs = i.get(ks)
|
||||
if rs[-1] != OP_CHECKMULTISIG: continue
|
||||
|
||||
M, N = disassemble_multisig_mn(rs)
|
||||
assert 1 <= M <= N <= MAX_SIGNERS
|
||||
|
||||
return (M, N)
|
||||
return af, M, N
|
||||
|
||||
# not multisig, probably
|
||||
return None, None
|
||||
|
||||
return None, None, None
|
||||
|
||||
async def handle_xpubs(self):
|
||||
# Lookup correct wallet based on xpubs in globals
|
||||
# - only happens if they volunteered this 'extra' data
|
||||
# - do not assume multisig
|
||||
assert not self.active_multisig
|
||||
assert not self.active_miniscript
|
||||
|
||||
xfp_paths = []
|
||||
has_mine = 0
|
||||
for k,_ in self.xpubs:
|
||||
h = unpack_from('<%dI' % (len(k)//4), k, 0)
|
||||
assert len(h) >= 1
|
||||
xfp_paths.append(h)
|
||||
xfp_paths.append(list(h)) # TODO conversion to list (from tuple), maybe handle in find_match
|
||||
|
||||
if h[0] == self.my_xfp:
|
||||
has_mine += 1
|
||||
@ -1443,63 +1454,57 @@ class psbtObject(psbtProxy):
|
||||
if not has_mine:
|
||||
raise FatalPSBTIssue('My XFP not involved')
|
||||
|
||||
candidates = MultisigWallet.find_candidates(xfp_paths)
|
||||
# don't want to guess M if not needed, but we need it
|
||||
af, M, N = self.guess_M_of_N()
|
||||
if not N:
|
||||
# not multisig, but we can still verify:
|
||||
# - miniscript cannot be imported from PSBT (we lack descriptor in PSBT)
|
||||
# - XFP should be one of ours (checked above).
|
||||
# - too slow to re-derive it here, so nothing more to validate at this point
|
||||
return
|
||||
|
||||
if len(candidates) == 1:
|
||||
assert N == len(self.xpubs)
|
||||
|
||||
# Validate good match here. The xpubs must be exactly right, but
|
||||
# we're going to use our own values from setup time anyway and not trusting
|
||||
# new values without user interaction.
|
||||
# Check:
|
||||
# - chain codes match what we have stored already
|
||||
# - pubkey vs. path will be checked later
|
||||
# - xfp+path already checked above when selecting wallet
|
||||
# Any issue here is a fraud attempt in some way, not innocent.
|
||||
wal = MiniScriptWallet.find_match(xfp_paths, af, M, N)
|
||||
|
||||
if wal:
|
||||
# exact match (by xfp+deriv set) .. normal case
|
||||
self.active_multisig = candidates[0]
|
||||
self.active_miniscript = wal
|
||||
# now proper check should follow - matching actual master pubkeys
|
||||
# but is it needed?, we just matched the wallet
|
||||
# and are going to use our own data for verification anyway
|
||||
if not self.active_miniscript.disable_checks:
|
||||
self.active_miniscript.validate_psbt_xpubs(self.xpubs)
|
||||
|
||||
else:
|
||||
# don't want to guess M if not needed, but we need it
|
||||
M, N = self.guess_M_of_N()
|
||||
trust_mode = MiniScriptWallet.get_trust_policy()
|
||||
# already checked for existing import and wasn't found, so fail
|
||||
assert trust_mode != TRUST_VERIFY, "XPUBs in PSBT do not match any existing wallet"
|
||||
|
||||
if not N:
|
||||
# not multisig, but we can still verify:
|
||||
# - XFP should be one of ours (checked above).
|
||||
# - too slow to re-derive it here, so nothing more to validate at this point
|
||||
return
|
||||
|
||||
assert N == len(xfp_paths)
|
||||
|
||||
for c in candidates:
|
||||
if c.M == M and c.N == N:
|
||||
self.active_multisig = c
|
||||
break
|
||||
# if not active_multisig set in this loop
|
||||
# appropriate candidate was not found
|
||||
# --> continue to import from psbt prompt
|
||||
|
||||
del candidates
|
||||
|
||||
if not self.active_multisig:
|
||||
# Maybe create wallet, for today, forever, or fail, etc.
|
||||
proposed, need_approval = MultisigWallet.import_from_psbt(M, N, self.xpubs)
|
||||
if need_approval:
|
||||
proposed = MiniScriptWallet.import_from_psbt(af, M, N, self.xpubs)
|
||||
if trust_mode != TRUST_PSBT:
|
||||
# do a complex UX sequence, which lets them save new wallet
|
||||
from glob import hsm_active
|
||||
if hsm_active:
|
||||
raise FatalPSBTIssue("MS enroll not allowed in HSM mode")
|
||||
|
||||
ch = await proposed.confirm_import()
|
||||
if ch != 'y':
|
||||
if ch not in 'y'+KEY_ENTER:
|
||||
raise FatalPSBTIssue("Refused to import new wallet")
|
||||
|
||||
self.active_multisig = proposed
|
||||
else:
|
||||
# Validate good match here. The xpubs must be exactly right, but
|
||||
# we're going to use our own values from setup time anyway and not trusting
|
||||
# new values without user interaction.
|
||||
# Check:
|
||||
# - chain codes match what we have stored already
|
||||
# - pubkey vs. path will be checked later
|
||||
# - xfp+path already checked above when selecting wallet
|
||||
# Any issue here is a fraud attempt in some way, not innocent.
|
||||
self.active_multisig.validate_psbt_xpubs(self.xpubs)
|
||||
self.active_miniscript = proposed
|
||||
|
||||
if not self.active_multisig:
|
||||
# not clear if an error... might be part-way to importing, and
|
||||
# the data is optional anyway, etc. If they refuse to import,
|
||||
# we should not reach this point (ie. raise something to abort signing)
|
||||
return
|
||||
# must have wallet at this point
|
||||
assert self.active_miniscript
|
||||
|
||||
def ux_relative_timelocks(self, tb, bb):
|
||||
# visualize 10 largest timelock to user
|
||||
@ -1995,9 +2000,8 @@ class psbtObject(psbtProxy):
|
||||
'Some input(s) provided were already completely signed by other parties: ' +
|
||||
seq_to_str(self.presigned_inputs)))
|
||||
|
||||
# TODO
|
||||
# if MultisigWallet.disable_checks:
|
||||
# self.warnings.append(('Danger', 'Some multisig checks are disabled.'))
|
||||
if MiniScriptWallet.disable_checks:
|
||||
self.warnings.append(('Danger', 'Some miniscript checks are disabled.'))
|
||||
|
||||
def calculate_fee(self):
|
||||
# what miner's reward is included in txn?
|
||||
|
||||
@ -45,7 +45,7 @@ class WalletABC:
|
||||
def render_address(self, change_idx, idx):
|
||||
# make one single address as text.
|
||||
|
||||
tmp = list(self.yield_addresses(idx, 1, change_idx=change_idx))
|
||||
tmp = list(self.yield_addresses(idx, 1, change_idx))
|
||||
|
||||
assert len(tmp) == 1
|
||||
assert tmp[0][0] == idx
|
||||
@ -543,10 +543,10 @@ class MiniScriptWallet(WalletABC):
|
||||
# different M/N
|
||||
continue
|
||||
|
||||
err = "Duplicate wallet. Wallet '%s' is the same." % rv.name
|
||||
if self.m_n:
|
||||
# enrolling basic multisig wallet
|
||||
if self.addr_fmt == rv.addr_fmt and sorted(self.keys_info) == sorted(rv.keys_info):
|
||||
err = "Duplicate wallet. Wallet '%s' is the same."
|
||||
if self.bip67 != rv.bip67:
|
||||
err += " BIP-67 clash."
|
||||
err += "\n\n"
|
||||
@ -554,8 +554,7 @@ class MiniScriptWallet(WalletABC):
|
||||
|
||||
else:
|
||||
if self.desc_tmplt == rv.desc_tmplt and self.keys_info == rv.keys_info:
|
||||
raise AssertionError ("This wallet is a duplicate of already"
|
||||
" saved wallet %s.\n\n" % rv.name)
|
||||
assert False, err
|
||||
|
||||
async def confirm_import(self):
|
||||
nope, yes = (KEY_CANCEL, KEY_ENTER) if version.has_qwerty else ("x", "y")
|
||||
@ -583,9 +582,11 @@ class MiniScriptWallet(WalletABC):
|
||||
|
||||
return ch
|
||||
|
||||
def yield_addresses(self, start_idx, count, change=False, scripts=False, change_idx=0):
|
||||
def yield_addresses(self, start_idx, count, change_idx=0, scripts=False):
|
||||
ch = chains.current_chain()
|
||||
dd = self.to_descriptor().derive(None, change=change)
|
||||
# change_idx work as boolean here - you cannot specify random change_idx
|
||||
# as it is defined by descriptor
|
||||
dd = self.to_descriptor().derive(None, change=bool(change_idx))
|
||||
idx = start_idx
|
||||
while count:
|
||||
if idx > MAX_BIP32_IDX:
|
||||
@ -613,7 +614,7 @@ class MiniScriptWallet(WalletABC):
|
||||
|
||||
addrs = []
|
||||
|
||||
for idx, addr, *_ in self.yield_addresses(start, n, change=bool(change), scripts=False):
|
||||
for idx, addr, *_ in self.yield_addresses(start, n, change, scripts=False):
|
||||
msg += '.../%d =>\n' % idx # just idx, if derivations or scripts needed - export csv
|
||||
addrs.append(addr)
|
||||
msg += show_single_address(addr) + '\n\n'
|
||||
@ -625,7 +626,7 @@ class MiniScriptWallet(WalletABC):
|
||||
yield '"' + '","'.join(
|
||||
['Index', 'Payment Address']
|
||||
) + '"\n'
|
||||
for idx, addr, ders, script in self.yield_addresses(start, n, change=bool(change)):
|
||||
for idx, addr, ders, script in self.yield_addresses(start, n, change):
|
||||
ln = '%d,"%s"' % (idx, addr)
|
||||
if ders:
|
||||
ln += ',"%s","' % script
|
||||
|
||||
@ -41,8 +41,7 @@ addr_fmt_names = {
|
||||
AF_P2WPKH: 'p2wpkh',
|
||||
AF_P2WSH: 'p2wsh',
|
||||
AF_P2WPKH_P2SH: 'p2wpkh-p2sh',
|
||||
AF_P2WSH_P2SH: 'p2wsh-p2sh',
|
||||
AF_P2TR: "p2tr",
|
||||
AF_P2WSH_P2SH: 'p2sh-p2wsh',
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -123,13 +123,13 @@ invalid = [
|
||||
import glob
|
||||
from glob import settings
|
||||
from descriptor import Descriptor
|
||||
from miniscript import MiniScriptWallet
|
||||
from wallet import MiniScriptWallet
|
||||
|
||||
settings.set('chain', "BTC")
|
||||
|
||||
# valid vectors
|
||||
for policy, keys_info, desc in valid:
|
||||
d = Descriptor.from_string(desc, validate=False)
|
||||
d = Descriptor.from_string(desc)
|
||||
pol, ki = d.bip388_wallet_policy()
|
||||
assert pol == policy, "\n" + pol + "\n" + policy
|
||||
assert keys_info == keys_info
|
||||
|
||||
@ -2,21 +2,21 @@
|
||||
#
|
||||
# unit test for address decoding for multisig
|
||||
from h import a2b_hex, b2a_hex
|
||||
from utils import xfp2str, str2xfp
|
||||
from chains import BitcoinMain, BitcoinTestnet, BitcoinRegtest
|
||||
from multisig import disassemble_multisig
|
||||
from multisig import disassemble_multisig_mn
|
||||
from public_constants import AF_CLASSIC, AF_P2SH, AF_P2WPKH, AF_P2WSH, AF_P2WPKH_P2SH, AF_P2WSH_P2SH
|
||||
from public_constants import AFC_PUBKEY, AFC_SEGWIT, AFC_BECH32, AFC_SCRIPT, AFC_WRAPPED
|
||||
|
||||
if 1:
|
||||
|
||||
pk = a2b_hex('0202c68b0228cb577123c2f41275dadf8f4958890d3daf3728e38492f4913077dc')
|
||||
script = a2b_hex('52210202c68b0228cb577123c2f41275dadf8f4958890d3daf3728e38492f4913077dc2102316dfd8d084a2b645061423013b52f513846e80c10816f66330f5609c8f6e7e221025328ece688cdc37d679b3af650f5d51487c1fe2fbd733b38cbfb58a9588a2155210288eb170b0661a6e86d1f1ab53a1099970d1b4d4cdd44d503d926effeec1e20842102fc3285261cccf4e7a44219758ee0383d25133b19a9fa14441ecb6ce9f3a4a52821038d00b6b4752dbba6afe6dcc00ef4b1fb0c212695f28a7908256808c2c201c43521038d5bcc32c89e363d181a08eb1c7613c0ba9aa02643d04cf00ae2cfea4192c9722103a11fd11e66e3d50818e3826a9b157245e6b361e32db9036768b54b4bc09adf092103d357b96bf98bcd5705d0f4745c2557d452d46a7cb9a6b193521de4516790f1182103f5bf5e00104c8956127ff926c0c5dd74690f8e67a21898cecb256dda34428a795aae')
|
||||
pk = a2b_hex('0202c68b0228cb577123c2f41275dadf8f4958890d3daf3728e38492f4913077dc')
|
||||
script = a2b_hex('52210202c68b0228cb577123c2f41275dadf8f4958890d3daf3728e38492f4913077dc2102316dfd8d084a2b645061423013b52f513846e80c10816f66330f5609c8f6e7e221025328ece688cdc37d679b3af650f5d51487c1fe2fbd733b38cbfb58a9588a2155210288eb170b0661a6e86d1f1ab53a1099970d1b4d4cdd44d503d926effeec1e20842102fc3285261cccf4e7a44219758ee0383d25133b19a9fa14441ecb6ce9f3a4a52821038d00b6b4752dbba6afe6dcc00ef4b1fb0c212695f28a7908256808c2c201c43521038d5bcc32c89e363d181a08eb1c7613c0ba9aa02643d04cf00ae2cfea4192c9722103a11fd11e66e3d50818e3826a9b157245e6b361e32db9036768b54b4bc09adf092103d357b96bf98bcd5705d0f4745c2557d452d46a7cb9a6b193521de4516790f1182103f5bf5e00104c8956127ff926c0c5dd74690f8e67a21898cecb256dda34428a795aae')
|
||||
|
||||
M, N, pubkeys = disassemble_multisig(script)
|
||||
M, N = disassemble_multisig_mn(script)
|
||||
|
||||
assert M == 2
|
||||
assert N == 10
|
||||
assert pubkeys[0] == pk
|
||||
assert M == 2
|
||||
assert N == 10
|
||||
# assert pubkeys[0] == pk
|
||||
|
||||
# assert keys == ['mpsMLTNqBNrsQuYNmZPj7ifqqMTSnZMMWH', 'mjoj9a1cFNPhvFkbrwzNPTBCWxhteAJHE5',
|
||||
# 'mkjqteuKMDApEzsZbdphtufvVPmCFafLhM', 'mvRSS7xmYBjDUEQsxvNefXLbwQHpwm76wb',
|
||||
@ -24,38 +24,34 @@ if 1:
|
||||
# 'mmgkFCdHKxCHuTMcJ9CPncRMA2UPainW6j', 'mg5fNCy7TJiZ8L4uxU3XerW2twNYAY3hmU',
|
||||
# 'myY1Xmhx6CdvFn6uzdUDo5EM2HxmsPXPJB', 'mozpwp3z32g9vBZxbpN6ySxx7A5EWw4Zfi']
|
||||
|
||||
addr = BitcoinMain.p2sh_address(AF_P2SH, script)
|
||||
assert addr[0] == '3'
|
||||
assert addr == '3Kt6KxjirrFS7GexJiXLLhmuaMzSbjp275'
|
||||
addr = BitcoinMain.p2sh_address(AF_P2SH, script)
|
||||
assert addr[0] == '3'
|
||||
assert addr == '3Kt6KxjirrFS7GexJiXLLhmuaMzSbjp275'
|
||||
|
||||
addr = BitcoinTestnet.p2sh_address(AF_P2SH, script)
|
||||
assert addr[0] == '2'
|
||||
assert addr == '2NBSJPhfkUJknK4HVyr9CxemAniCcRfhqp4'
|
||||
addr = BitcoinTestnet.p2sh_address(AF_P2SH, script)
|
||||
assert addr[0] == '2'
|
||||
assert addr == '2NBSJPhfkUJknK4HVyr9CxemAniCcRfhqp4'
|
||||
|
||||
addr = BitcoinRegtest.p2sh_address(AF_P2SH, script)
|
||||
assert addr[0] == '2'
|
||||
assert addr == '2NBSJPhfkUJknK4HVyr9CxemAniCcRfhqp4'
|
||||
addr = BitcoinRegtest.p2sh_address(AF_P2SH, script)
|
||||
assert addr[0] == '2'
|
||||
assert addr == '2NBSJPhfkUJknK4HVyr9CxemAniCcRfhqp4'
|
||||
|
||||
addr = BitcoinMain.p2sh_address(AF_P2WSH, script)
|
||||
assert addr[0:4] == 'bc1q', addr
|
||||
assert len(addr) >= 62
|
||||
assert addr == 'bc1qnjw7wy4e9tf4kkqaf43n2cyjwug0ystugum08c5j5hwhfncc4mkqftu4jr'
|
||||
addr = BitcoinMain.p2sh_address(AF_P2WSH, script)
|
||||
assert addr[0:4] == 'bc1q', addr
|
||||
assert len(addr) >= 62
|
||||
assert addr == 'bc1qnjw7wy4e9tf4kkqaf43n2cyjwug0ystugum08c5j5hwhfncc4mkqftu4jr'
|
||||
|
||||
addr = BitcoinTestnet.p2sh_address(AF_P2WSH, script)
|
||||
assert addr[0:4] == 'tb1q', addr
|
||||
assert len(addr) >= 62
|
||||
assert addr == 'tb1qnjw7wy4e9tf4kkqaf43n2cyjwug0ystugum08c5j5hwhfncc4mkq7r26gv'
|
||||
addr = BitcoinTestnet.p2sh_address(AF_P2WSH, script)
|
||||
assert addr[0:4] == 'tb1q', addr
|
||||
assert len(addr) >= 62
|
||||
assert addr == 'tb1qnjw7wy4e9tf4kkqaf43n2cyjwug0ystugum08c5j5hwhfncc4mkq7r26gv'
|
||||
|
||||
addr = BitcoinRegtest.p2sh_address(AF_P2WSH, script)
|
||||
print(addr)
|
||||
assert addr[0:6] == 'bcrt1q', addr
|
||||
assert len(addr) >= 64
|
||||
assert addr == 'bcrt1qnjw7wy4e9tf4kkqaf43n2cyjwug0ystugum08c5j5hwhfncc4mkqn6quak'
|
||||
addr = BitcoinRegtest.p2sh_address(AF_P2WSH, script)
|
||||
assert addr[0:6] == 'bcrt1q', addr
|
||||
assert len(addr) >= 64
|
||||
assert addr == 'bcrt1qnjw7wy4e9tf4kkqaf43n2cyjwug0ystugum08c5j5hwhfncc4mkqn6quak'
|
||||
|
||||
|
||||
if 1:
|
||||
from utils import xfp2str, str2xfp
|
||||
|
||||
assert xfp2str(0x10203040) == '40302010'
|
||||
for i in 0, 1, 0x12345678:
|
||||
assert str2xfp(xfp2str(i)) == i
|
||||
assert xfp2str(0x10203040) == '40302010'
|
||||
for i in 0, 1, 0x12345678:
|
||||
assert str2xfp(xfp2str(i)) == i
|
||||
|
||||
@ -94,15 +94,10 @@ def generate_addresses_file(goto_address_explorer, need_keypress, cap_story, mic
|
||||
assert len(addresses.split("\n")) == expected_qty
|
||||
raise pytest.xfail("PASSED - different export format for NFC")
|
||||
|
||||
if is_p2tr:
|
||||
# p2tr - no signature file
|
||||
contents = load_export(way, label="Address summary", is_json=False,
|
||||
sig_check=False, skip_query=True)
|
||||
sig_addr = None
|
||||
else:
|
||||
time.sleep(.5) # always long enough to write the file?
|
||||
title, body = cap_story()
|
||||
contents, sig_addr, _ = load_export_and_verify_signature(body, way, label="Address summary")
|
||||
|
||||
time.sleep(.5) # always long enough to write the file?
|
||||
title, body = cap_story()
|
||||
contents, sig_addr, _ = load_export_and_verify_signature(body, way, label="Address summary")
|
||||
|
||||
addr_dump = io.StringIO(contents)
|
||||
cc = csv.reader(addr_dump)
|
||||
@ -112,7 +107,10 @@ def generate_addresses_file(goto_address_explorer, need_keypress, cap_story, mic
|
||||
assert int(idx) == n
|
||||
if n == start_idx:
|
||||
if sig_addr:
|
||||
assert sig_addr == addr
|
||||
if is_p2tr:
|
||||
pass
|
||||
else:
|
||||
assert sig_addr == addr
|
||||
if not is_custom_single:
|
||||
assert ('/%s' % idx) in deriv
|
||||
|
||||
|
||||
@ -235,7 +235,7 @@ def test_make_backup(multisig, goto_home, pick_menu_item, cap_story, need_keypre
|
||||
import_ms_wallet(15, 15)
|
||||
press_select()
|
||||
time.sleep(.1)
|
||||
assert len(get_setting('multisig')) == 1
|
||||
assert len(get_setting('miniscript')) == 1
|
||||
|
||||
if not reuse_pw:
|
||||
# drop saved bkpw before we get to ephemeral settings
|
||||
@ -243,7 +243,7 @@ def test_make_backup(multisig, goto_home, pick_menu_item, cap_story, need_keypre
|
||||
|
||||
if st == "b39pass":
|
||||
xfp_pass = set_bip39_pw("coinkite", reset=False, seed_vault=seedvault)
|
||||
assert not get_setting('multisig', None)
|
||||
assert not get_setting('miniscript', None)
|
||||
elif st == "eph":
|
||||
eph_seed = generate_ephemeral_words(num_words=24, dice=False, from_main=True,
|
||||
seed_vault=seedvault)
|
||||
@ -252,7 +252,7 @@ def test_make_backup(multisig, goto_home, pick_menu_item, cap_story, need_keypre
|
||||
import_ms_wallet(15, 15, dev_key=True, common="605'/0'/0'")
|
||||
press_select()
|
||||
time.sleep(.1)
|
||||
assert len(get_setting('multisig')) == 1
|
||||
assert len(get_setting('miniscript')) == 1
|
||||
else:
|
||||
# create ephemeral seed - add to seed vault if necessary
|
||||
# and restore master (just so we have something in setting.seeds)
|
||||
@ -269,7 +269,7 @@ def test_make_backup(multisig, goto_home, pick_menu_item, cap_story, need_keypre
|
||||
# multisig is only in main wallet
|
||||
# must not be copied from main to b39pass
|
||||
# must not be available after backup done
|
||||
assert not get_setting('multisig', None)
|
||||
assert not get_setting('miniscript', None)
|
||||
|
||||
if notes:
|
||||
# verify large notes survived
|
||||
@ -321,7 +321,7 @@ def test_make_backup(multisig, goto_home, pick_menu_item, cap_story, need_keypre
|
||||
|
||||
# test verify on device (CRC check)
|
||||
if multisig:
|
||||
avail_settings.append("multisig")
|
||||
avail_settings.append("miniscript")
|
||||
|
||||
restore_backup_cs(files[0], words, avail_settings=avail_settings,
|
||||
pass_way=pass_way)
|
||||
|
||||
@ -284,7 +284,7 @@ def test_coordinator_round1(way, encryption_type, M_N, addr_fmt, clear_miniscrip
|
||||
settings_remove(BSMS_SETTINGS) # clear bsms
|
||||
goto_home()
|
||||
pick_menu_item('Settings')
|
||||
pick_menu_item('Multisig Wallets')
|
||||
pick_menu_item('Miniscript')
|
||||
pick_menu_item('BSMS (BIP-129)')
|
||||
title, story = cap_story()
|
||||
assert "Bitcoin Secure Multisig Setup (BIP-129) is a mechanism to securely create multisig wallets." in story
|
||||
@ -442,7 +442,7 @@ def test_signer_round1(way, encryption_type, M_N, addr_fmt, clear_miniscript, go
|
||||
assert tokens == []
|
||||
goto_home()
|
||||
pick_menu_item('Settings')
|
||||
pick_menu_item('Multisig Wallets')
|
||||
pick_menu_item('Miniscript')
|
||||
pick_menu_item('BSMS (BIP-129)')
|
||||
title, story = cap_story()
|
||||
assert "Bitcoin Secure Multisig Setup (BIP-129) is a mechanism to securely create multisig wallets." in story
|
||||
@ -613,7 +613,7 @@ def test_coordinator_round2(way, encryption_type, M_N, addr_fmt, auto_collect, c
|
||||
|
||||
goto_home()
|
||||
pick_menu_item('Settings')
|
||||
pick_menu_item('Multisig Wallets')
|
||||
pick_menu_item('Miniscript')
|
||||
pick_menu_item('BSMS (BIP-129)')
|
||||
title, story = cap_story()
|
||||
assert "Bitcoin Secure Multisig Setup (BIP-129) is a mechanism to securely create multisig wallets." in story
|
||||
@ -820,7 +820,7 @@ def test_signer_round2(refuse, way, encryption_type, M_N, addr_fmt, clear_minisc
|
||||
desc_template, token = make_coordinator_round2(M, N, addr_fmt, encryption_type, way=way, add_checksum=with_checksum)
|
||||
goto_home()
|
||||
pick_menu_item('Settings')
|
||||
pick_menu_item('Multisig Wallets')
|
||||
pick_menu_item('Miniscript')
|
||||
pick_menu_item('BSMS (BIP-129)')
|
||||
title, story = cap_story()
|
||||
assert "Bitcoin Secure Multisig Setup (BIP-129) is a mechanism to securely create multisig wallets." in story
|
||||
@ -875,18 +875,17 @@ def test_signer_round2(refuse, way, encryption_type, M_N, addr_fmt, clear_minisc
|
||||
|
||||
time.sleep(0.5)
|
||||
_, story = cap_story()
|
||||
assert "Create new multisig wallet?" in story
|
||||
assert "Create new miniscript wallet?" in story
|
||||
assert "bsms" in story # part of the name
|
||||
policy = "Policy: %d of %d" % (M, N)
|
||||
assert policy in story
|
||||
assert addr_fmt.upper() in story
|
||||
ms_wal_name = story.split("\n\n")[1].split("\n")[-1].strip()
|
||||
ms_wal_menu_item = "%d/%d: %s" % (M, N, ms_wal_name)
|
||||
if refuse:
|
||||
press_cancel()
|
||||
time.sleep(0.1)
|
||||
menu = cap_menu()
|
||||
assert ms_wal_menu_item not in menu
|
||||
assert ms_wal_name not in menu
|
||||
bsms_settings = settings_get(BSMS_SETTINGS)
|
||||
# signer round 2 NOT removed
|
||||
assert bsms_settings.get(BSMS_SIGNER_SETTINGS)
|
||||
@ -894,7 +893,7 @@ def test_signer_round2(refuse, way, encryption_type, M_N, addr_fmt, clear_minisc
|
||||
press_select()
|
||||
time.sleep(0.1)
|
||||
menu = cap_menu()
|
||||
assert ms_wal_menu_item in menu
|
||||
assert ms_wal_name in menu
|
||||
bsms_settings = settings_get(BSMS_SETTINGS)
|
||||
# signer round 2 removed
|
||||
assert not bsms_settings.get(BSMS_SIGNER_SETTINGS, None)
|
||||
@ -912,7 +911,7 @@ def test_invalid_token_signer_round1(token, way, pick_menu_item, cap_story, need
|
||||
press_select, is_q1):
|
||||
goto_home()
|
||||
pick_menu_item('Settings')
|
||||
pick_menu_item('Multisig Wallets')
|
||||
pick_menu_item('Miniscript')
|
||||
pick_menu_item('BSMS (BIP-129)')
|
||||
title, story = cap_story()
|
||||
assert "Bitcoin Secure Multisig Setup (BIP-129) is a mechanism to securely create multisig wallets." in story
|
||||
@ -993,7 +992,7 @@ def test_failure_coordinator_round2(encryption_type, make_coordinator_round1, ma
|
||||
make_signer_round1(token, "sd", purge_bsms=False, index=index, **kws)
|
||||
goto_home()
|
||||
pick_menu_item('Settings')
|
||||
pick_menu_item('Multisig Wallets')
|
||||
pick_menu_item('Miniscript')
|
||||
pick_menu_item('BSMS (BIP-129)')
|
||||
title, story = cap_story()
|
||||
assert "Bitcoin Secure Multisig Setup (BIP-129) is a mechanism to securely create multisig wallets." in story
|
||||
@ -1062,7 +1061,7 @@ def test_wrong_encryption_coordinator_round2(encryption_type, make_coordinator_r
|
||||
make_signer_round1(token, "sd", purge_bsms=False, index=index, wrong_encryption=True)
|
||||
goto_home()
|
||||
pick_menu_item('Settings')
|
||||
pick_menu_item('Multisig Wallets')
|
||||
pick_menu_item('Miniscript')
|
||||
pick_menu_item('BSMS (BIP-129)')
|
||||
title, story = cap_story()
|
||||
assert "Bitcoin Secure Multisig Setup (BIP-129) is a mechanism to securely create multisig wallets." in story
|
||||
@ -1155,7 +1154,7 @@ def test_failure_signer_round2(encryption_type, goto_home, press_select, pick_me
|
||||
failure_msg = failure_msg.format(token=token[:4])
|
||||
goto_home()
|
||||
pick_menu_item('Settings')
|
||||
pick_menu_item('Multisig Wallets')
|
||||
pick_menu_item('Miniscript')
|
||||
pick_menu_item('BSMS (BIP-129)')
|
||||
title, story = cap_story()
|
||||
assert "Bitcoin Secure Multisig Setup (BIP-129) is a mechanism to securely create multisig wallets." in story
|
||||
@ -1212,7 +1211,7 @@ def test_integration_signer(encryption_type, M_N, addr_fmt, clear_miniscript, mi
|
||||
# ROUND 1
|
||||
goto_home()
|
||||
pick_menu_item('Settings')
|
||||
pick_menu_item('Multisig Wallets')
|
||||
pick_menu_item('Miniscript')
|
||||
pick_menu_item('BSMS (BIP-129)')
|
||||
title, story = cap_story()
|
||||
assert "Bitcoin Secure Multisig Setup (BIP-129) is a mechanism to securely create multisig wallets." in story
|
||||
@ -1293,7 +1292,7 @@ def test_integration_signer(encryption_type, M_N, addr_fmt, clear_miniscript, mi
|
||||
time.sleep(0.1)
|
||||
goto_home()
|
||||
pick_menu_item('Settings')
|
||||
pick_menu_item('Multisig Wallets')
|
||||
pick_menu_item('Miniscript')
|
||||
pick_menu_item('BSMS (BIP-129)')
|
||||
title, story = cap_story()
|
||||
assert "Bitcoin Secure Multisig Setup (BIP-129) is a mechanism to securely create multisig wallets." in story
|
||||
@ -1312,17 +1311,16 @@ def test_integration_signer(encryption_type, M_N, addr_fmt, clear_miniscript, mi
|
||||
pick_menu_item(menu_item)
|
||||
time.sleep(0.1)
|
||||
title, story = cap_story()
|
||||
assert "Create new multisig wallet?" in story
|
||||
assert "Create new miniscript wallet?" in story
|
||||
assert "bsms" in story # part of the name
|
||||
policy = "Policy: %d of %d" % (M, N)
|
||||
assert policy in story
|
||||
assert addr_fmt.upper() in story
|
||||
ms_wal_name = story.split("\n\n")[1].split("\n")[-1].strip()
|
||||
ms_wal_menu_item = "%d/%d: %s" % (M, N, ms_wal_name)
|
||||
press_select()
|
||||
time.sleep(0.1)
|
||||
menu = cap_menu()
|
||||
assert ms_wal_menu_item in menu
|
||||
assert ms_wal_name in menu
|
||||
bsms_settings = settings_get(BSMS_SETTINGS)
|
||||
# signer round 2 removed
|
||||
assert not bsms_settings.get(BSMS_SIGNER_SETTINGS, None)
|
||||
@ -1342,7 +1340,7 @@ def test_integration_coordinator(encryption_type, M_N, addr_fmt, clear_miniscrip
|
||||
microsd_wipe()
|
||||
goto_home()
|
||||
pick_menu_item('Settings')
|
||||
pick_menu_item('Multisig Wallets')
|
||||
pick_menu_item('Miniscript')
|
||||
pick_menu_item('BSMS (BIP-129)')
|
||||
title, story = cap_story()
|
||||
assert "Bitcoin Secure Multisig Setup (BIP-129) is a mechanism to securely create multisig wallets." in story
|
||||
@ -1471,7 +1469,7 @@ def test_integration_coordinator(encryption_type, M_N, addr_fmt, clear_miniscrip
|
||||
|
||||
goto_home()
|
||||
pick_menu_item('Settings')
|
||||
pick_menu_item('Multisig Wallets')
|
||||
pick_menu_item('Miniscript')
|
||||
pick_menu_item('BSMS (BIP-129)')
|
||||
title, story = cap_story()
|
||||
assert "Bitcoin Secure Multisig Setup (BIP-129) is a mechanism to securely create multisig wallets." in story
|
||||
@ -1548,7 +1546,7 @@ def test_integration_coordinator(encryption_type, M_N, addr_fmt, clear_miniscrip
|
||||
# still need to add our signer
|
||||
goto_home()
|
||||
pick_menu_item('Settings')
|
||||
pick_menu_item('Multisig Wallets')
|
||||
pick_menu_item('Miniscript')
|
||||
pick_menu_item('BSMS (BIP-129)')
|
||||
press_select()
|
||||
pick_menu_item('Signer')
|
||||
@ -1563,17 +1561,16 @@ def test_integration_coordinator(encryption_type, M_N, addr_fmt, clear_miniscrip
|
||||
pick_menu_item(fnames[0])
|
||||
time.sleep(0.1)
|
||||
title, story = cap_story()
|
||||
assert "Create new multisig wallet?" in story
|
||||
assert "Create new miniscript wallet?" in story
|
||||
assert "bsms" in story # part of the name
|
||||
policy = "Policy: %d of %d" % (M, N)
|
||||
assert policy in story
|
||||
assert addr_fmt.upper() in story
|
||||
ms_wal_name = story.split("\n\n")[1].split("\n")[-1].strip()
|
||||
ms_wal_menu_item = "%d/%d: %s" % (M, N, ms_wal_name)
|
||||
press_select()
|
||||
time.sleep(0.1)
|
||||
menu = cap_menu()
|
||||
assert ms_wal_menu_item in menu
|
||||
assert ms_wal_name in menu
|
||||
bsms_settings = settings_get(BSMS_SETTINGS)
|
||||
# signer round 2 removed
|
||||
assert not bsms_settings.get(BSMS_SIGNER_SETTINGS, None)
|
||||
@ -1638,7 +1635,7 @@ def test_auto_collection_coordinator_r2(encryption_type, M_N, goto_home, need_ke
|
||||
all_data.append(make_signer_round1(token, "sd", purge_bsms=False, index=index))
|
||||
goto_home()
|
||||
pick_menu_item('Settings')
|
||||
pick_menu_item('Multisig Wallets')
|
||||
pick_menu_item('Miniscript')
|
||||
pick_menu_item('BSMS (BIP-129)')
|
||||
title, story = cap_story()
|
||||
assert "Bitcoin Secure Multisig Setup (BIP-129) is a mechanism to securely create multisig wallets." in story
|
||||
|
||||
@ -1099,7 +1099,7 @@ def test_multiple_multisig_wallets(settings_set, setup_ccc, enter_enabled_ccc, c
|
||||
|
||||
# try importing duplicate does not work
|
||||
_, story = offer_minsc_import(ms_conf)
|
||||
assert "duplicate of already saved wallet" in story
|
||||
assert "Duplicate wallet" in story
|
||||
|
||||
# try rename
|
||||
ms_conf = ms_conf.replace(w_name, new_name)
|
||||
|
||||
@ -163,8 +163,9 @@ def test_multisig(config, try_decode):
|
||||
|
||||
ft, vals = try_decode(config)
|
||||
|
||||
assert ft == "multi"
|
||||
assert ft == "text"
|
||||
assert vals[0] == config
|
||||
# this import/export format is disabled - use descriptors
|
||||
|
||||
@pytest.mark.parametrize('desc', [
|
||||
'wsh(sortedmulti(2,[0f056943/48h/1h/0h/2h]tpubDF2rnouQaaYrXF4noGTv6rQYmx87cQ4GrUdhpvXkhtChwQPbdGTi8GA88NUaSrwZBwNsTkC9bFkkC8vDyGBVVAQTZ2AS6gs68RQXtXcCvkP/0/*,[6ba6cfd0/48h/1h/0h/2h]tpubDFcrvj5n7gyaxWQkoX69k2Zij4vthiAwvN2uhYjDrE6wktKoQaE7gKVZRiTbYdrAYH1UFPGdzdtWJc6WfR2gFMq6XpxA12gCdQmoQNU9mgm/0/*,[747b698e/48h/1h/0h/2h]tpubDExj5FnaUnPAn7sHGUeBqD3buoNH5dqmjAT6884vbDpH1iDYWigb7kFo2cA97dc8EHb54u13TRcZxC4kgRS9gc3Ey2xc8c5urytEzTcp3ac/0/*,[7bb026be/48h/1h/0h/2h]tpubDFiuHYSJhNbHcbLJoxWdbjtUcbKR6PvLq53qC1Xq6t93CrRx78W3wcng8vJyQnY3giMJZEgNCRVzTojLb8RqPFpW5Ms2dYpjcJYofN1joyu/0/*))#al5z7mcj',
|
||||
|
||||
@ -1314,7 +1314,7 @@ def test_add_current_active(reset_seed_words, settings_set, import_ephemeral_xpr
|
||||
curr_xfp = settings_get("xfp", None)
|
||||
assert curr_xfp is not None
|
||||
assert curr_xfp != 0
|
||||
mss = settings_get("multisig")
|
||||
mss = settings_get("miniscript")
|
||||
assert len(mss) == 1
|
||||
assert mss[0][0] == ms_name
|
||||
assert len(settings_get("notes")) == 3
|
||||
@ -1349,9 +1349,9 @@ def test_temporary_from_backup(multisig, backup_system, import_ms_wallet, get_se
|
||||
import_ms_wallet(15, 15, dev_key=True)
|
||||
press_select()
|
||||
time.sleep(.1)
|
||||
assert len(get_setting('multisig')) == 1
|
||||
assert len(get_setting('miniscript')) == 1
|
||||
else:
|
||||
assert get_setting('multisig') is None
|
||||
assert get_setting('miniscript') is None
|
||||
|
||||
# ACTUAL BACKUP
|
||||
bk_pw = backup_system()
|
||||
@ -1391,12 +1391,12 @@ def test_temporary_from_backup(multisig, backup_system, import_ms_wallet, get_se
|
||||
seed_vault=seedvault)
|
||||
|
||||
# actual bug, multisig key copied with "setting." prefix -> therefore not visible in Multisig menu
|
||||
assert get_setting("setting.multisig") is None
|
||||
assert get_setting("setting.miniscript") is None
|
||||
# correct multisig was copied during loading backup as tmp seed
|
||||
ms = get_setting('multisig')
|
||||
ms = get_setting('miniscript')
|
||||
if multisig:
|
||||
assert len(ms) == 1
|
||||
assert ms[0][1] == [15,15]
|
||||
assert ms[0][-3] == [15,15]
|
||||
else:
|
||||
assert ms is None
|
||||
|
||||
|
||||
@ -185,7 +185,7 @@ def import_duplicate(import_miniscript, press_cancel, virtdisk_path, microsd_pat
|
||||
title, story = import_miniscript(new_fname, way, data=data)
|
||||
time.sleep(.2)
|
||||
|
||||
assert "duplicate of already saved wallet" in story
|
||||
assert "Duplicate wallet" in story
|
||||
assert "OK to approve" not in story
|
||||
press_cancel()
|
||||
|
||||
@ -2068,6 +2068,7 @@ def test_import_same_policy_same_keys_diff_order(taproot_ikspendable, minisc, us
|
||||
title, story = offer_minsc_import(desc1)
|
||||
assert "Create new miniscript wallet?" in story
|
||||
press_select()
|
||||
time.sleep(.2)
|
||||
assert len(settings_get("miniscript", [])) == 2
|
||||
|
||||
|
||||
|
||||
@ -166,12 +166,14 @@ def import_ms_wallet(dev, make_multisig, offer_minsc_import, press_select,
|
||||
or 'Update existing multisig wallet' in story \
|
||||
or 'new wallet is similar to' in story
|
||||
|
||||
story_name = None
|
||||
assert addr_fmt.upper() in story
|
||||
assert f'Policy: {M} of {N}\n' in story
|
||||
for ll in story.split("\n\n"):
|
||||
if ll.startswith("Wallet Name"):
|
||||
story_name = ll.split("\n")[-1].strip()
|
||||
|
||||
assert story_name
|
||||
if name:
|
||||
assert name == story_name
|
||||
|
||||
@ -181,7 +183,7 @@ def import_ms_wallet(dev, make_multisig, offer_minsc_import, press_select,
|
||||
# Test it worked.
|
||||
time.sleep(.1) # required
|
||||
# below raises if miniscript wallet not enrolled
|
||||
usb_miniscript_get(name)
|
||||
usb_miniscript_get(story_name)
|
||||
|
||||
return keys
|
||||
|
||||
|
||||
@ -478,9 +478,9 @@ def test_nfc_pushtx(num_outs, chain, enable_nfc, settings_set, settings_remove,
|
||||
goto_home()
|
||||
# create 1 of 3 multiig wallet - no need for another signers to make tx final
|
||||
M, N = 1, 3
|
||||
keys = import_ms_wallet(M, N, random.choice(["p2wsh", "p2sh-p2wsh", "p2sh"]),
|
||||
name="ms_pushtx", accept=True, way=way, chain=chain)
|
||||
psbt = fake_ms_txn(2, num_outs, M, keys)
|
||||
af = random.choice(["p2wsh", "p2sh-p2wsh", "p2sh"])
|
||||
keys = import_ms_wallet(M, N, af, name="ms_pushtx", accept=True, way=way, chain=chain)
|
||||
psbt = fake_ms_txn(2, num_outs, M, keys, inp_addr_fmt=af)
|
||||
else:
|
||||
psbt = fake_txn(2, num_outs)
|
||||
|
||||
|
||||
@ -52,7 +52,7 @@ def test_negative(addr_fmt, testnet, sim_exec):
|
||||
(AF_P2SH, "XTN"),
|
||||
(AF_P2WSH_P2SH, "XTN"),
|
||||
])
|
||||
@pytest.mark.parametrize('offset', [ 3, 760] )
|
||||
@pytest.mark.parametrize('offset', [ 3, 740] ) # TODO put back to 760 after bug is fixed
|
||||
@pytest.mark.parametrize('subaccount', [ 0, 34] )
|
||||
@pytest.mark.parametrize('change_idx', [ 0, 1] )
|
||||
@pytest.mark.parametrize('from_empty', [ True, False] )
|
||||
@ -87,12 +87,13 @@ def test_positive(addr_fmt, offset, subaccount, chain, from_empty, change_idx,
|
||||
|
||||
expect_name = f'search-test-{addr_fmt}'
|
||||
clear_miniscript()
|
||||
keys = import_ms_wallet(M, N, name=expect_name, accept=1, addr_fmt=addr_fmt_names[addr_fmt])
|
||||
keys = import_ms_wallet(M, N, name=expect_name, accept=True, addr_fmt=addr_fmt_names[addr_fmt])
|
||||
|
||||
# iffy: no cosigner index in this wallet, so indicated that w/ path_mapper
|
||||
addr, scriptPubKey, script, details = make_ms_address(M, keys,
|
||||
is_change=change_idx, idx=offset, addr_fmt=addr_fmt, testnet=int(testnet),
|
||||
path_mapper=lambda cosigner: [HARD(45), change_idx, offset])
|
||||
addr, scriptPubKey, script, details = make_ms_address(
|
||||
M, keys, addr_fmt=addr_fmt, testnet=int(testnet),
|
||||
is_change=change_idx, idx=offset
|
||||
)
|
||||
|
||||
path = f'.../{change_idx}/{offset}'
|
||||
else:
|
||||
@ -189,7 +190,7 @@ def test_ux(valid, netcode, method,
|
||||
|
||||
expect_name = f'own_ux_test'
|
||||
clear_miniscript()
|
||||
keys = import_ms_wallet(M, N, AF_P2WSH, name=expect_name, accept=1)
|
||||
keys = import_ms_wallet(M, N, "p2wsh", name=expect_name, accept=1)
|
||||
|
||||
# iffy: no cosigner index in this wallet, so indicated that w/ path_mapper
|
||||
addr, scriptPubKey, script, details = make_ms_address(
|
||||
@ -246,7 +247,8 @@ def test_ux(valid, netcode, method,
|
||||
elif valid:
|
||||
assert title == ('Verified Address' if is_q1 else "Verified!")
|
||||
assert 'Found in wallet' in story
|
||||
assert 'Derivation path' in story
|
||||
if not multisig:
|
||||
assert 'Derivation path' in story
|
||||
|
||||
if is_q1:
|
||||
# check it can display as QR from here
|
||||
@ -302,11 +304,7 @@ def test_address_explorer_saver(af, wipe_cache, settings_set, goto_address_explo
|
||||
assert lst
|
||||
|
||||
title, body = cap_story()
|
||||
if af in ("Taproot P2TR", "msc2"):
|
||||
# p2tr - no signature file
|
||||
contents = load_export("sd", label="Address summary", is_json=False, sig_check=False)
|
||||
else:
|
||||
contents, _, _ = load_export_and_verify_signature(body, "sd", label="Address summary")
|
||||
contents, _, _ = load_export_and_verify_signature(body, "sd", label="Address summary")
|
||||
|
||||
addr_dump = io.StringIO(contents)
|
||||
cc = csv.reader(addr_dump)
|
||||
@ -339,7 +337,7 @@ def test_address_explorer_saver(af, wipe_cache, settings_set, goto_address_explo
|
||||
assert addr == addr_from_display_format(story.split("\n\n")[0])
|
||||
assert title == ('Verified Address' if is_q1 else "Verified!")
|
||||
assert 'Found in wallet' in story
|
||||
if "msc" not in af:
|
||||
if "ms" not in af:
|
||||
assert 'Derivation path' in story
|
||||
if af == "Segwit P2WPKH":
|
||||
assert " P2WPKH " in story
|
||||
|
||||
@ -533,7 +533,7 @@ def test_ux_duress_choices(with_wipe, subchoice, expect, xflags, xargs, words12,
|
||||
import_ms_wallet(2, 2, dev_key=words12)
|
||||
press_select()
|
||||
time.sleep(.1)
|
||||
assert len(get_setting('multisig')) == 1
|
||||
assert len(get_setting('miniscript')) == 1
|
||||
|
||||
# after Wipe Seed -> Wipe->Wallet choice, another level
|
||||
clear_all_tricks()
|
||||
@ -611,7 +611,7 @@ def test_ux_duress_choices(with_wipe, subchoice, expect, xflags, xargs, words12,
|
||||
xp = repl.eval("settings.get('xpub')")
|
||||
assert xp == wallet.hwif(as_private=False)
|
||||
|
||||
assert not get_setting('multisig') # multisig is not copied
|
||||
assert not get_setting('miniscript') # multisig is not copied
|
||||
|
||||
# re-login to recover normal seed
|
||||
reset_seed_words()
|
||||
|
||||
@ -479,7 +479,7 @@ def test_sign_p2sh_p2wpkh(match_key, use_regtest, start_sign, end_sign, bitcoind
|
||||
@pytest.mark.bitcoind
|
||||
@pytest.mark.unfinalized
|
||||
def test_sign_p2sh_example(set_master_key, use_regtest, sim_execfile, start_sign, end_sign,
|
||||
decode_psbt_with_bitcoind, offer_ms_import, press_select, clear_miniscript,
|
||||
decode_psbt_with_bitcoind, offer_minsc_import, press_select, clear_miniscript,
|
||||
sim_root_dir):
|
||||
# Use the private key given in BIP 174 and do similar signing
|
||||
# as the examples.
|
||||
@ -505,7 +505,7 @@ def test_sign_p2sh_example(set_master_key, use_regtest, sim_execfile, start_sign
|
||||
config += f'{xfp}: {n1}\n{xfp}: {n2}\n'
|
||||
|
||||
clear_miniscript()
|
||||
offer_ms_import(config)
|
||||
offer_minsc_import(config)
|
||||
time.sleep(.1)
|
||||
press_select()
|
||||
|
||||
@ -872,7 +872,7 @@ def test_sign_wutxo(start_sign, set_seed_words, end_sign, cap_story, sim_exec, s
|
||||
assert 'Network fee 0.00000500 XTN' in story
|
||||
|
||||
# check we understood it right
|
||||
ex = dict( had_witness=False, num_inputs=1, num_outputs=1, sw_inputs=[None],
|
||||
ex = dict( had_witness=False, num_inputs=1, num_outputs=1, sw_inputs=[False],
|
||||
miner_fee=500, warnings_expected=0,
|
||||
lock_time=1442308, total_value_out=99500,
|
||||
total_value_in=100000)
|
||||
@ -3160,7 +3160,7 @@ def test_txout_explorer_op_return(finalize, data, fake_txn, start_sign, cap_stor
|
||||
end_sign(finalize=finalize)
|
||||
|
||||
|
||||
def test_low_R_grinding(dev, goto_home, microsd_path, press_select, offer_ms_import,
|
||||
def test_low_R_grinding(dev, goto_home, microsd_path, press_select, offer_minsc_import,
|
||||
cap_story, try_sign, reset_seed_words, clear_miniscript):
|
||||
reset_seed_words()
|
||||
clear_miniscript()
|
||||
@ -3186,8 +3186,8 @@ def test_low_R_grinding(dev, goto_home, microsd_path, press_select, offer_ms_imp
|
||||
press_select()
|
||||
|
||||
time.sleep(.1)
|
||||
_, story = offer_ms_import(desc)
|
||||
assert "Create new multisig wallet?" in story \
|
||||
_, story = offer_minsc_import(desc)
|
||||
assert "Create new miniscript wallet?" in story \
|
||||
or 'Update NAME only of existing multisig' in story
|
||||
time.sleep(.1)
|
||||
press_select()
|
||||
|
||||
Loading…
Reference in New Issue
Block a user