From 428caf3d359b0def172fa418d392070007d1097a Mon Sep 17 00:00:00 2001 From: matejcik Date: Thu, 4 Nov 2021 12:32:38 +0100 Subject: [PATCH] fix(python/build_tx): make build_tx work again after blockbook protection upgrades Also improve script type selection. --- python/.changelog.d/1896.fixed | 1 + python/tools/build_tx.py | 42 ++++++++++++++++++++++++++-------- 2 files changed, 33 insertions(+), 10 deletions(-) create mode 100644 python/.changelog.d/1896.fixed diff --git a/python/.changelog.d/1896.fixed b/python/.changelog.d/1896.fixed new file mode 100644 index 000000000..45bf970fe --- /dev/null +++ b/python/.changelog.d/1896.fixed @@ -0,0 +1 @@ +Updated `tools/build_tx.py` to work with Blockbook's API protections. diff --git a/python/tools/build_tx.py b/python/tools/build_tx.py index 9e1103428..7457ef308 100755 --- a/python/tools/build_tx.py +++ b/python/tools/build_tx.py @@ -26,6 +26,16 @@ from trezorlib.cli import ChoiceType from trezorlib.cli.btc import INPUT_SCRIPTS, OUTPUT_SCRIPTS from trezorlib.protobuf import to_dict +SESSION = requests.Session() +SESSION.headers.update({"User-Agent": "trezorlib"}) + +BITCOIN_CORE_INPUT_TYPES = { + "scripthash": messages.InputScriptType.SPENDADDRESS, + "pubkeyhash": messages.InputScriptType.SPENDP2SHWITNESS, + "witness_v0_keyhash": messages.InputScriptType.SPENDWITNESS, + "witness_v1_taproot": messages.InputScriptType.SPENDP2SHWITNESS, +} + def echo(*args, **kwargs): return click.echo(*args, err=True, **kwargs) @@ -65,11 +75,10 @@ def _get_inputs_interactive(blockbook_url): if not prev: break prev_hash, prev_index = prev - address_n = prompt("BIP-32 path to derive the key", type=tools.parse_path) txhash = prev_hash.hex() tx_url = blockbook_url + txhash - r = requests.get(tx_url) + r = SESSION.get(tx_url) if not r.ok: raise click.ClickException(f"Failed to fetch URL: {tx_url}") @@ -79,21 +88,34 @@ def _get_inputs_interactive(blockbook_url): tx = btc.from_json(tx_json) txes[txhash] = tx + try: + from_address = tx_json["vout"][prev_index]["scriptPubKey"]["address"] + echo(f"From address: {from_address}") + except Exception: + pass amount = tx.bin_outputs[prev_index].amount echo(f"Input amount: {amount}") + address_n = prompt("BIP-32 path to derive the key", type=tools.parse_path) + + reported_type = tx_json["vout"][prev_index]["scriptPubKey"].get("type") + if reported_type in BITCOIN_CORE_INPUT_TYPES: + script_type = BITCOIN_CORE_INPUT_TYPES[reported_type] + click.echo(f"Script type: {script_type.name}") + else: + script_type = prompt( + "Input type", + type=ChoiceType(INPUT_SCRIPTS), + default=_default_script_type(address_n, INPUT_SCRIPTS), + ) + if isinstance(script_type, str): + script_type = INPUT_SCRIPTS[script_type] + sequence = prompt( "Sequence Number to use (RBF opt-in enabled by default)", type=int, default=0xFFFFFFFD, ) - script_type = prompt( - "Input type", - type=ChoiceType(INPUT_SCRIPTS), - default=_default_script_type(address_n, INPUT_SCRIPTS), - ) - if isinstance(script_type, str): - script_type = INPUT_SCRIPTS[script_type] new_input = messages.TxInputType( address_n=address_n, @@ -151,7 +173,7 @@ def sign_interactive(): coin = prompt("Coin name", default="Bitcoin") blockbook_host = prompt("Blockbook server", default="btc1.trezor.io") - if not requests.get(f"https://{blockbook_host}/api").ok: + if not SESSION.get(f"https://{blockbook_host}/api/block/1").ok: raise click.ClickException("Could not connect to blockbook") blockbook_url = f"https://{blockbook_host}/api/tx-specific/"