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}")
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)