Example #1
0
def b32decode(bech: String) -> Tuple[str, List[int]]:
    "Validate a bech32 string, and determine HRP and data."

    if isinstance(bech, str):
        bech = bech.strip()

    if isinstance(bech, bytes):
        bech = bech.decode("ascii")

    if not all(47 < ord(x) < 123 for x in bech):
        raise BTClibValueError(f"ASCII character outside [48-122]: {bech}")
    if bech.lower() != bech and bech.upper() != bech:
        raise BTClibValueError(f"mixed case: {bech}")
    bech = bech.lower()

    # it is fine to limit bech32 _bitcoin_addresses_ at 90 chars,
    # but it should be enforced when working with addresses,
    # not here at bech32 level.
    # e.g. Lightning Network uses bech32 without such limitation
    # if len(bech) > 90:
    #     raise BTClibValueError(f"Bech32 string length ({len(bech)}) > 90")

    pos = bech.rfind("1")  # find the separator between hrp and data
    if pos == -1:
        raise BTClibValueError(f"missing HRP: {bech}")
    if pos == 0:
        raise BTClibValueError(f"empty HRP: {bech}")
    if pos + 7 > len(bech):
        raise BTClibValueError(f"too short checksum: {bech}")

    hrp = bech[:pos]

    if any(x not in _ALPHABET for x in bech[pos + 1:]):
        raise BTClibValueError(f"invalid data characters: {bech}")
    data = [_ALPHABET.find(x) for x in bech[pos + 1:]]

    if _verify_checksum(hrp, data):
        return hrp, data[:-6]
    raise BTClibValueError(f"invalid checksum: {bech}")
Example #2
0
def has_segwit_prefix(addr: String) -> bool:

    str_addr = addr.strip().lower() if isinstance(
        addr, str) else addr.decode("ascii")
    return any(
        str_addr.startswith(NETWORKS[net].hrp + "1") for net in NETWORKS)