Source code for cfx_address.utils

from typing import (
    Optional,
    Union,
    overload,
)
from typing_extensions import (
    Literal
)

from eth_utils.address import (
    is_hex_address,
    to_checksum_address,
)

from cfx_address._utils import (
    validate_hex_address,
    validate_network_id,
    eth_eoa_address_to_cfx_hex,
    public_key_to_cfx_hex,
)
from cfx_address.address import Base32Address

from cfx_utils.exceptions import (
    Base32AddressNotMatch,
    AddressNotMatch,
)
from cfx_utils.types import (
    ChecksumAddress,
)

validate_base32 = Base32Address.validate
is_valid_base32 = Base32Address.is_valid_base32


@overload
def normalize_to(address: str, network_id: None, verbose: bool = False) -> ChecksumAddress:
    ...


@overload
def normalize_to(address: str, network_id: int, verbose: bool = False) -> Base32Address:
    ...


def normalize_to(
    address: str, network_id: Union[int, None], verbose: bool = False
) -> Union[Base32Address, ChecksumAddress]:
    """
    normalize a hex or base32 address to target network or hex address

    :param str address: a base32 address or hex address
    :param Union[int, None] network_id: target network id. None will return hex checksum address
    :return Union[Base32Address, HexAddress]: a normalized base32 address or hex checksum address, depending on network id
    """
    if network_id is not None:
        return Base32Address(address, network_id, verbose)
    else:
        if is_hex_address(address):
            return to_checksum_address(address)
        # error will be raised if address is not a Base32Address
        return Base32Address(address).hex_address


[docs] def validate_address_agaist_network_id( address: str, network_id: Union[int, None], accept_hex: Optional[bool] = False ) -> Literal[True]: """ Validate address in specific network context. Error will be raised only if: 1. address validity checking: address is a base32 address or hex / base32 address if accept_hex 2. network id validity checking: the network id of the address should be same as network_id, this step will be skipped if address is hex address or network_id is None :param str address: address to validate :param Union[int, None] network_id: if is None, then network id checking will be skipped :param Optional[bool] accept_hex: whether a hex address is accepted, if. Defaults to False :raises AddressNotMatch: hex address is received when accept_hex is not True :raises Base32AddressNotMatch: the network id of address does not equal to network_id :return Literal[True]: returns True if no exceptions are raised >>> from cfx_address.utils import validate_address_agaist_network_id >>> address = Base32Address.zero_address(1) >>> validate_address_agaist_network_id(address, 1) True >>> validate_address_agaist_network_id(address.hex_address, 1, True) True >>> validate_address_agaist_network_id(address, None) True >>> validate_address_agaist_network_id(address.hex_address, None) Traceback (most recent call last): ... cfx_utils.exceptions.AddressNotMatch: hex address is not accepted >>> validate_address_agaist_network_id(address, 1029) Traceback (most recent call last): ... cfx_utils.exceptions.Base32AddressNotMatch: expects address of network id 1029, receives address of network id 1 """ if is_hex_address(address): if accept_hex: return True raise AddressNotMatch("hex address is not accepted") else: # the address is Base32Address (or invalid) address_network_id = Base32Address.decode(address)["network_id"] if address_network_id == network_id or network_id is None: return True raise Base32AddressNotMatch( f"expects address of network id {network_id}, " f"receives address of network id {address_network_id}" )
__all__ = [ "validate_hex_address", "validate_network_id", "eth_eoa_address_to_cfx_hex", "validate_base32", "is_valid_base32", "validate_address_agaist_network_id", "public_key_to_cfx_hex", ]