Guide: Address Validation

Validating a destination address before sending funds prevents costly mistakes. libcrypto verifies checksums for every supported format locally, with no network calls.

Quick check

from libcrypto import validate_address

validate_address("1BgGZ9tcN4rm9KBzDn7KprQz87SZ26SAMH")             # True
validate_address("1BgGZ9tcN4rm9KBzDn7KprQz87SZ26SAMX")             # False (bad checksum)
validate_address("bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4")     # True
validate_address("0x7E5F4552091A69125d5DfCb7b8C2659029395Bdf")     # True

Restrict to a network

from libcrypto import validate_address

validate_address("1BgGZ9tcN4rm9KBzDn7KprQz87SZ26SAMH", "bitcoin")   # True
validate_address("1BgGZ9tcN4rm9KBzDn7KprQz87SZ26SAMH", "litecoin")  # False

Inspect an address

from libcrypto import get_address_info

info = get_address_info("bc1pmfr3p9j00pfxjh0zmgp99y8zftmd3s5pmedqhyptwy6lm87hf5sspknck9")
print(info.valid)             # True
print(info.address_format)    # bech32m
print(info.address_type)      # p2tr
print(info.networks)          # ('bitcoin',)
print(info.witness_version)   # 1
print(info.payload.hex())     # 32-byte taproot output key

Ethereum EIP-55 checksums

from libcrypto import is_valid_ethereum_address, to_checksum_address

# Mixed-case addresses are always checksum-verified.
is_valid_ethereum_address("0x7E5F4552091A69125d5DfCb7b8C2659029395Bdf")  # True
is_valid_ethereum_address("0x7E5f4552091a69125d5dfcb7b8c2659029395bdf")  # False (bad checksum)

# All-lowercase addresses carry no checksum; require one when you need safety.
is_valid_ethereum_address("0x7e5f...bdf", require_checksum=True)          # False

# Normalize to checksummed form.
to_checksum_address("0x7e5f4552091a69125d5dfcb7b8c2659029395bdf")

Handling ambiguity

Some coins share Base58 version bytes. get_address_info(...).networks returns all possible networks in that case, so you always know when a positive match is ambiguous:

from libcrypto import get_address_info

get_address_info("1BgGZ9tcN4rm9KBzDn7KprQz87SZ26SAMH").networks
# ('bitcoin', 'bitcoin_cash')

When you need a single definitive answer, pass the expected network to validate_address.

Decoding for advanced use

from libcrypto import decode_base58check_address, decode_segwit_address

version, payload = decode_base58check_address("1BgGZ9tcN4rm9KBzDn7KprQz87SZ26SAMH")
# version == 0x00, len(payload) == 20

hrp, wv, program = decode_segwit_address("bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4")
# hrp == "bc", wv == 0, len(program) == 20

Both raise InvalidFormatError / AddressError for malformed input, so wrap them in try/except or use the non-raising validate_address / get_address_info helpers.