diff --git a/node/utxo_endpoints.py b/node/utxo_endpoints.py index 70a040cd6..54556a550 100644 --- a/node/utxo_endpoints.py +++ b/node/utxo_endpoints.py @@ -451,7 +451,10 @@ def utxo_transfer(): }), 400 # Verify pubkey → address - expected_addr = _addr_from_pk_fn(public_key) + try: + expected_addr = _addr_from_pk_fn(public_key) + except ValueError: + return jsonify({'error': 'Invalid public_key'}), 400 if from_address != expected_addr: return jsonify({ 'error': 'Public key does not match from_address', diff --git a/tests/test_utxo_transfer_json_validation.py b/tests/test_utxo_transfer_json_validation.py index 510ea6ebb..cfa351bc7 100644 --- a/tests/test_utxo_transfer_json_validation.py +++ b/tests/test_utxo_transfer_json_validation.py @@ -58,6 +58,22 @@ def test_utxo_transfer_rejects_structured_string_fields(client, field, value): assert response.get_json() == {"error": f"{field} must be a string"} +def test_utxo_transfer_rejects_malformed_public_key_material(client, monkeypatch): + monkeypatch.setattr( + utxo_endpoints, + "_addr_from_pk_fn", + lambda public_key: (_ for _ in ()).throw(ValueError("bad hex")), + ) + + response = client.post( + "/utxo/transfer", + json=_transfer_payload(public_key="not-hex"), + ) + + assert response.status_code == 400 + assert response.get_json() == {"error": "Invalid public_key"} + + def test_utxo_transfer_still_reports_missing_trimmed_string_fields(client): response = client.post( "/utxo/transfer",