adjust input explorer for edge branch

This commit is contained in:
scgbckbone 2026-03-11 13:55:39 +01:00 committed by doc-hex
parent aa72433207
commit 42c8e3e8c0
4 changed files with 61 additions and 48 deletions

View File

@ -1688,7 +1688,7 @@ class TXInpExplorer(TXExplorer):
item += "=== UTXO ===\n\n%s %s\n\n%s\n\n" % (val, unit, spk)
if addr:
item += show_single_address(addr) + "\n\n"
item += "Address Format: %s\n\n" % chains.addr_fmt_str(inp.addr_fmt)
item += "Address Format: %s\n\n" % chains.AF_TO_STR_AF[inp.af]
qr_items.append(addr)
if self.user_auth_action.psbt.txn_version >= 2:
@ -1702,35 +1702,49 @@ class TXInpExplorer(TXExplorer):
item += "Input has relative %s\n\n" % msg
psbt_item = ""
if inp.required_key:
our = [inp.required_key] if isinstance(inp.required_key, bytes) else inp.required_key
psbt_item += "Our key%s:\n\n" % ("s" if len(our) > 1 else "")
for k in our:
pth = inp.subpaths[k]
if inp.sp_idxs:
psbt_item += "Our key%s:\n\n" % ("s" if len(inp.sp_idxs) > 1 else "")
for i in inp.sp_idxs:
# get node required
if inp.taproot_subpaths:
pubk = inp.taproot_subpaths[i][0]
sp = inp.taproot_subpaths[i][1][2]
else:
pubk = inp.subpaths[i][0]
sp = inp.subpaths[i][1]
pth = inp.parse_xfp_path(sp)
k = inp.get(pubk)
psbt_item += "%s:\n%s\n\n" % (keypath_to_str(pth, prefix="%s/" % xfp2str(pth[0])),
b2a_hex(k).decode())
M = None
if inp.is_multisig:
if inp.is_miniscript:
ks_coord = inp.witness_script or inp.redeem_script
if ks_coord:
ks = self.user_auth_action.psbt.get(ks_coord)
ks = inp.get(ks_coord)
from multisig import disassemble_multisig_mn
from psbt import disassemble_multisig_mn
try:
M, N = disassemble_multisig_mn(ks)
psbt_item += "Multisig: %dof%d\n\n" % (M, N)
except: pass
if inp.part_sigs:
# do not show XFPs in case input is fully signed --> elif
if inp.part_sigs or inp.taproot_script_sigs:
# do not show XFPs in case input is fully signed
# only part_sig should be available, as we haven't signed yet so added_sigs empty
done = []
for pk, pth in inp.subpaths.items():
if pk in inp.part_sigs:
done.append(xfp2str(pth[0]))
if inp.part_sigs:
signed = {inp.get(k) for k, _ in inp.part_sigs}
for pk, pth in inp.subpaths:
if inp.get(pk) in signed:
done.append(xfp2str(inp.parse_xfp_path(pth)[0]))
else: # inp.taproot_script_sigs
signed = {xo for xo, _ in inp.get_taproot_script_sigs()}
for pk, val in inp.taproot_subpaths:
if inp.get(pk) in signed:
done.append(xfp2str(inp.parse_xfp_path(val[2])[0]))
if inp.fully_signed or (M and (len(done) >= M)):
psbt_item += "Input fully signed.\n\n"
@ -1740,14 +1754,15 @@ class TXInpExplorer(TXExplorer):
psbt_item += " %s\n" % xfp
psbt_item += "\n"
if inp.sighash and (inp.sighash != SIGHASH_ALL):
# only show sighash value to the user if it is non-standard
psbt_item += "sighash: %s\n\n" % {
1: "ALL", 2: "NONE", 3: "SINGLE",
1 | 0x80: "ALL|ANYONECANPAY",
2 | 0x80: "NONE|ANYONECANPAY",
3 | 0x80: "SINGLE|ANYONECANPAY",
}[inp.sighash]
if inp.sighash is not None:
# only show sighash value to the user if it is non-standard for particular script type
if (inp.af == AF_P2TR and inp.sighash != 0) or (inp.af != AF_P2TR and inp.sighash != 1):
psbt_item += "sighash: %s\n\n" % {
0: "DEFAULT", 1: "ALL", 2: "NONE", 3: "SINGLE",
1 | 0x80: "ALL|ANYONECANPAY",
2 | 0x80: "NONE|ANYONECANPAY",
3 | 0x80: "SINGLE|ANYONECANPAY",
}[inp.sighash]
if psbt_item:
psbt_item = "=== PSBT ===\n\n" + psbt_item

View File

@ -2618,7 +2618,7 @@ def explorer_input_check(cap_story, press_cancel, need_keypress, is_q1, verify_q
n = BIP32Node.from_wallet_key(simulator_fixed_xprv if chain == "BTC" else simulator_fixed_tprv)
for pk, der in parsed_our_keys.items():
assert bytes.fromhex(pk) == n.subkey_for_path(der.split("/", 1)[-1]).sec()
assert bytes.fromhex(pk) == n.subkey_for_path(der.split("/", 1)[-1]).sec()[1 if af == "p2tr" else 0:]
# MULTISIG
if parsed_multisig is None:
@ -2638,7 +2638,10 @@ def explorer_input_check(cap_story, press_cancel, need_keypress, is_q1, verify_q
# SIGHASH
if parsed_sighash is None:
assert sighash in [None, "ALL"]
if af == "p2tr":
assert sighash in [None, "DEFAULT"]
else:
assert sighash in [None, "ALL"]
else:
assert sighash == parsed_sighash

View File

@ -3571,16 +3571,16 @@ def test_fwd_slash_in_name(import_ms_wallet, clear_miniscript, pick_menu_item, n
@pytest.mark.parametrize("complete", [True, False, None])
@pytest.mark.parametrize("addr_fmt", ["p2wsh", "p2sh", "p2sh-p2wsh"])
def test_txin_explorer(dev, chain, M_N, addr_fmt, fake_ms_txn, start_sign, settings_set, txin_explorer,
cap_story, pytestconfig, import_ms_wallet, complete, clear_ms):
cap_story, pytestconfig, import_ms_wallet, complete, clear_miniscript):
# TODO This test MUST be run with --psbt2 flag on and off
clear_ms()
clear_miniscript()
settings_set("chain", chain)
inp_amount = 100000000
num_ins = 2
M, N = M_N
keys = import_ms_wallet(M, N, name='txin_expl', accept=True, netcode=chain,
descriptor=True, addr_fmt=addr_fmt)
keys = import_ms_wallet(M, N, name='txin_expl', accept=True, chain=chain,
addr_fmt=addr_fmt)
all_xfps = [xfp2str(k[0]) for k in keys][:-1] # remove myself
if complete:
@ -3599,7 +3599,7 @@ def test_txin_explorer(dev, chain, M_N, addr_fmt, fake_ms_txn, start_sign, setti
inp.part_sigs[pk] = os.urandom(71)
psbt = fake_ms_txn(num_ins, 1, M, keys, inp_af=unmap_addr_fmt[addr_fmt],
psbt = fake_ms_txn(num_ins, 1, M, keys, inp_addr_fmt=addr_fmt,
input_amount=inp_amount, psbt_v2=pytestconfig.getoption('psbt2'),
hack_psbt=hack)
@ -3607,17 +3607,16 @@ def test_txin_explorer(dev, chain, M_N, addr_fmt, fake_ms_txn, start_sign, setti
txin_explorer(num_ins, [(addr_fmt, inp_amount, 1, chain, (M,N), None, None, complete, target_xfps)])
def test_txin_explorer_our_sig(dev, fake_ms_txn, start_sign, settings_set, clear_ms,
def test_txin_explorer_our_sig(dev, fake_ms_txn, start_sign, settings_set, clear_miniscript,
txin_explorer, cap_story, pytestconfig, import_ms_wallet):
# TODO This test MUST be run with --psbt2 flag on and off
clear_ms()
clear_miniscript()
inp_amount = 100000000
num_ins = 3
M, N = 5,7
af = "p2wsh"
keys = import_ms_wallet(M, N, name='txin_expl', accept=True, netcode="XTN",
descriptor=True, addr_fmt="p2wsh")
keys = import_ms_wallet(M, N, name='txin_expl', accept=True, chain="XTN", addr_fmt="p2wsh")
my_xfp = xfp2str(keys[-1][0])
@ -3629,7 +3628,7 @@ def test_txin_explorer_our_sig(dev, fake_ms_txn, start_sign, settings_set, clear
inp.part_sigs[pk] = os.urandom(71)
psbt = fake_ms_txn(num_ins, 1, M, keys, inp_af=unmap_addr_fmt[af],
psbt = fake_ms_txn(num_ins, 1, M, keys, inp_addr_fmt=af,
input_amount=inp_amount, psbt_v2=pytestconfig.getoption('psbt2'),
hack_psbt=hack)

View File

@ -3112,36 +3112,32 @@ def test_txout_explorer(chain, data, fake_txn, start_sign, settings_set, txout_e
txout_explorer(data, chain)
@pytest.mark.parametrize("chain", ["BTC", "XTN"])
@pytest.mark.parametrize("addr_fmt", ["p2wpkh", "p2pkh", "p2wpkh-p2sh"])
@pytest.mark.parametrize("addr_fmt", ["p2tr", "p2wpkh", "p2pkh", "p2wpkh-p2sh"])
def test_txin_explorer(chain, addr_fmt, fake_txn, start_sign, settings_set, txin_explorer,
cap_story, pytestconfig):
# TODO This test MUST be run with --psbt2 flag on and off
settings_set("chain", chain)
inp_amount = 1000000
num_ins = 3
if addr_fmt == "p2wpkh":
segwit = True
wrapped = False
sh = "SINGLE"
sh = "SINGLE" if chain == "BTC" else "ALL"
seq = 1100
elif addr_fmt == "p2pkh":
segwit = False
wrapped = False
sh = "ALL|ANYONECANPAY"
seq = SEQUENCE_LOCKTIME_TYPE_FLAG | (512 >> 9)
elif addr_fmt == "p2tr":
sh = "DEFAULT" if chain == "BTC" else "ALL"
seq = 500
else:
segwit = True
wrapped = True
sh = "SINGLE|ANYONECANPAY"
seq = 1
psbt = fake_txn(num_ins, 1, segwit_in=segwit, wrapped=wrapped,
psbt_v2=pytestconfig.getoption('psbt2'), input_amount=inp_amount,
psbt = fake_txn(num_ins, 1, addr_fmt=addr_fmt,
psbt_v2=pytestconfig.getoption('psbt2'),
sequences=[seq], sighashes=[sh])
start_sign(psbt)
txin_explorer(num_ins, [(addr_fmt, inp_amount, 1, chain, False, sh, seq)])
txin_explorer(num_ins, [(addr_fmt, 100_000_000, 1, chain, False, sh, seq)])
@pytest.mark.parametrize("finalize", [True, False])
@pytest.mark.parametrize("data", [
@ -3543,7 +3539,7 @@ def test_unknown_input_script(stype, fake_txn , start_sign, cap_story, use_testn
ins = [(af, 100000000, 0), ("p2wpkh", 100000000, 1)]
psbt = fake_txn(2, 2, segwit_in=True, change_outputs=[0], psbt_hacker=hack)
psbt = fake_txn(2, 2, addr_fmt="p2wpkh", psbt_hacker=hack)
start_sign(psbt)
title, story = cap_story()
assert title == "OK TO SEND?"