From 9994213912ce71e8f38eedca7360c886d5481504 Mon Sep 17 00:00:00 2001 From: Plastic-time <247457381+Plastic-time@users.noreply.github.com> Date: Thu, 22 Oct 2026 17:08:56 -0400 Subject: [PATCH] Accept 35-character testnet P2SH BTC addresses --- src/validators/crypto_addresses/btc_address.py | 9 +++++++-- tests/crypto_addresses/test_btc_address.py | 6 ++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/validators/crypto_addresses/btc_address.py b/src/validators/crypto_addresses/btc_address.py index f781f3b9..f4b5d94a 100644 --- a/src/validators/crypto_addresses/btc_address.py +++ b/src/validators/crypto_addresses/btc_address.py @@ -16,9 +16,14 @@ def _decode_base58(addr: str): def _validate_old_btc_address(addr: str): """Validate P2PKH and P2SH type address.""" - if len(addr) not in range(25, 35): + # Testnet P2SH addresses (version byte 0xc4) are 35 characters long. + if len(addr) not in range(25, 36): return False - decoded_bytes = _decode_base58(addr).to_bytes(25, "big") + decoded = _decode_base58(addr) + # Some 35-character strings decode to more than 25 bytes. + if decoded.bit_length() > 200: + return False + decoded_bytes = decoded.to_bytes(25, "big") header, checksum = decoded_bytes[:-4], decoded_bytes[-4:] return checksum == sha256(sha256(header).digest()).digest()[:4] diff --git a/tests/crypto_addresses/test_btc_address.py b/tests/crypto_addresses/test_btc_address.py index 96647eab..58f8de87 100644 --- a/tests/crypto_addresses/test_btc_address.py +++ b/tests/crypto_addresses/test_btc_address.py @@ -14,6 +14,8 @@ "1BvBMSEYstWetqTFn5Au4m4GFg7xJaNVN2", # P2SH (Pay to script hash) type "3J98t1WpEZ73CNmQviecrnyiWrnqRhWNLy", + # Testnet P2SH type (35 characters) + "2MzQwSSnBHWHqSAqtTVQ6v47XtaisrJa1Vc", # Bech32/segwit type "bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq", "bc1qc7slrfxkknqcq2jevvvkdgvrt8080852dfjewde450xdlk4ugp7szw5tk9", @@ -36,6 +38,10 @@ def test_returns_true_on_valid_btc_address(value: str): "1BvBMsEYstWetqTFn5Au4m4GFg7xJaNVN2", # incorrect checksum "3J98t1WpEZ73CNmQviecrnyiWrnqRhWNLz", + # incorrect testnet P2SH checksum + "2MzQwSSnBHWHqSAqtTVQ6v47XtaisrJa1Vd", + # 35 characters that decode to more than 25 bytes + "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz", ], ) def test_returns_failed_validation_on_invalid_btc_address(value: str):