diff --git a/newsfragments/2537.misc.rst b/newsfragments/2537.misc.rst new file mode 100644 index 0000000000..2f1063efb2 --- /dev/null +++ b/newsfragments/2537.misc.rst @@ -0,0 +1 @@ +Removed IBAN since it was an unused feature \ No newline at end of file diff --git a/tests/core/eth-module/test_iban.py b/tests/core/eth-module/test_iban.py deleted file mode 100644 index 71580bb5a3..0000000000 --- a/tests/core/eth-module/test_iban.py +++ /dev/null @@ -1,162 +0,0 @@ -import pytest - -from web3.exceptions import ( - InvalidAddress, -) - - -@pytest.mark.parametrize( - 'value,expected', - ( - ( - {"institution": 'XREG', "identifier": 'GAVOFYORK'}, - 'XE81ETHXREGGAVOFYORK', - ), - ) -) -def test_createIndirect(value, expected, w3): - actual = w3.eth.iban.createIndirect(value).toString() - assert actual == expected - - -@pytest.mark.parametrize( - 'value,expected', - ( - ( - '00c5496aee77c1ba1f0854206a26dda82a81d6d8', - InvalidAddress, - ), - ( - '0x00c5496aee77c1ba1f0854206a26dda82a81d6d8', - InvalidAddress, - ), - ( - '0x00c5496aEe77C1bA1f0854206A26DdA82a81D6D8', - 'XE7338O073KYGTWWZN0F2WZ0R8PX5ZPPZS', - ), - ( - '0x11c5496AEE77c1bA1f0854206a26dDa82A81D6D8', - 'XE1222Q908LN1QBBU6XUQSO1OHWJIOS46OO', - ), - ( - '0x52Dc504a422f0E2A9e7632A34a50f1a82F8224c7', - 'XE499OG1EH8ZZI0KXC6N83EKGT1BM97P2O7', - ), - ( - '0x0000A5327eAB78357CbF2aE8f3d49Fd9d90C7D22', - 'XE0600DQK33XDTYUCRI0KYM5ELAKXDWWF6', - ), - ( - '0x606060405261022e806100126000396000f360606040523615610074576000357c01000000000000000000000000000000000000000000000000000000009004806316216f391461007657806361bc221a146100995780637cf5dab0146100bc578063a5f3c23b146100e8578063d09de08a1461011d578063dcf537b11461014057610074565b005b610083600480505061016c565b6040518082815260200191505060405180910390f35b6100a6600480505061017f565b6040518082815260200191505060405180910390f35b6100d26004808035906020019091905050610188565b6040518082815260200191505060405180910390f35b61010760048080359060200190919080359060200190919050506101ea565b6040518082815260200191505060405180910390f35b61012a6004805050610201565b6040518082815260200191505060405180910390f35b6101566004808035906020019091905050610217565b6040518082815260200191505060405180910390f35b6000600d9050805080905061017c565b90565b60006000505481565b6000816000600082828250540192505081905550600060005054905080507f3496c3ede4ec3ab3686712aa1c238593ea6a42df83f98a5ec7df9834cfa577c5816040518082815260200191505060405180910390a18090506101e5565b919050565b6000818301905080508090506101fb565b92915050565b600061020d6001610188565b9050610214565b90565b60006007820290508050809050610229565b91905056', # noqa: E501 - InvalidAddress, - ), - ( - '0xd3CDA913deB6f67967B99D67aCDFa1712C293601', - InvalidAddress, - ), - ), -) -def test_fromAddress(value, expected, w3): - - if isinstance(expected, type) and issubclass(expected, Exception): - with pytest.raises(expected): - w3.eth.iban.fromAddress(value).toString() - return - - actual = w3.eth.iban.fromAddress(value).toString() - assert actual == expected - - -@pytest.mark.parametrize( - 'value,expected', - ( - ( - lambda: None, - False, - ), - ( - 'function', - False, - ), - ( - {}, - False, - ), - ( - '[]', - False, - ), - ( - '[1, 2]', - False, - ), - ( - '{}', - False, - ), - ( - '{"a": 123, "b" :3,}', - False, - ), - ( - '{"c" : 2}', - False, - ), - ( - 'XE81ETHXREGGAVOFYORK', - True, - ), - ( - 'XE82ETHXREGGAVOFYORK', - False, # control number is invalid - ), - ( - 'XE81ETCXREGGAVOFYORK', - False, - ), - ( - 'XE81ETHXREGGAVOFYORKD', - False, - ), - ( - 'XE81ETHXREGGaVOFYORK', - False, - ), - ( - 'XE7338O073KYGTWWZN0F2WZ0R8PX5ZPPZS', - True, - ), - ( - 'XE7438O073KYGTWWZN0F2WZ0R8PX5ZPPZS', - False, # control number is invalid - ), - ( - 'XD7338O073KYGTWWZN0F2WZ0R8PX5ZPPZS', - False, - ), - ( - 'XE1222Q908LN1QBBU6XUQSO1OHWJIOS46OO', - True, - ), - ), -) -def test_isValid(value, expected, w3): - actual = w3.eth.iban.isValid(value) - assert actual is expected - - iban = w3.eth.iban(value) - assert iban.isValid() is expected - - -@pytest.mark.parametrize( - "value,expected", - ( - ( - 'XE7338O073KYGTWWZN0F2WZ0R8PX5ZPPZS', - '0x00c5496aEe77C1bA1f0854206A26DdA82a81D6D8', - ), - ) -) -def test_toAddress(value, expected, w3): - actual = w3.eth.iban(value).address() - assert actual == expected diff --git a/web3/eth.py b/web3/eth.py index ef1c134911..22522ab7ef 100644 --- a/web3/eth.py +++ b/web3/eth.py @@ -77,9 +77,6 @@ TimeExhausted, TransactionNotFound, ) -from web3.iban import ( - Iban, -) from web3.method import ( DeprecatedMethod, Method, @@ -555,7 +552,6 @@ async def call( class Eth(BaseEth): account = Account() defaultContractFactory: Type[Union[Contract, ConciseContract, ContractCaller]] = Contract # noqa: E704,E501 - iban = Iban def namereg(self) -> NoReturn: raise NotImplementedError() diff --git a/web3/iban.py b/web3/iban.py deleted file mode 100644 index 750ad635d4..0000000000 --- a/web3/iban.py +++ /dev/null @@ -1,239 +0,0 @@ -import functools -import re -from typing import ( - Any, - Callable, - Union, -) - -from eth_typing import ( - Address, - ChecksumAddress, -) -from eth_utils import ( - is_string, - to_checksum_address, -) - -from web3._utils.compat import ( - TypedDict, -) -from web3._utils.validation import ( - validate_address, -) - -IbanOptions = TypedDict("IbanOptions", { - "institution": str, - "identifier": str, -}) - - -def pad_left_hex(value: str, num_bytes: int) -> str: - return value.rjust(num_bytes * 2, '0') - - -def iso13616Prepare(iban: str) -> str: - """ - Prepare an IBAN for mod 97 computation by moving the first - 4 chars to the end and transforming the letters to numbers - (A = 10, B = 11, ..., Z = 35), as specified in ISO13616. - - @method iso13616Prepare - @param {String} iban the IBAN - @returns {String} the prepared IBAN - """ - A = ord("A") - Z = ord("Z") - - iban = iban.upper() - iban = iban[4:] + iban[:4] - - def charfunc(n: str) -> str: - code = ord(n) - if code >= A and code <= Z: - return str(code - A + 10) - else: - return str(n) - - return "".join(map(charfunc, list(iban))) - - -def mod9710(iban: str) -> int: - """ - Calculates the MOD 97 10 of the passed IBAN as specified in ISO7064. - - @method mod9710 - @param {String} iban - @returns {Number} - """ - remainder = iban - block = None - - while len(remainder) > 2: - block = remainder[:9] - remainder = str(int(block) % 97) + remainder[len(block):] - - return int(remainder) % 97 - - -def baseN(num: int, b: int, numerals: str = "0123456789abcdefghijklmnopqrstuvwxyz") -> str: - """ - This prototype should be used to create - an iban object from iban correct string - - @param {String} iban - """ - return ((num == 0) and numerals[0]) or \ - (baseN(num // b, b, numerals).lstrip(numerals[0]) + numerals[num % b]) - - -class IsValid: - """ - Should be called to check if iban is correct - - Note: This is implemented as a descriptor so that it can be called as - either an instance method. - - @method isValid - @returns {Boolean} true if it is, otherwise false - """ - def __get__(self, instance: 'Iban', owner: str) -> Callable[[str], bool]: - if instance is None: - return self.validate - return functools.partial(self.validate, instance._iban) - - @staticmethod - def validate(iban_address: Any) -> bool: - if not is_string(iban_address): - return False - - if re.match(r"^XE[0-9]{2}(ETH[0-9A-Z]{13}|[0-9A-Z]{30,31})$", iban_address) and \ - mod9710(iso13616Prepare(iban_address)) == 1: - return True - - return False - - -class Iban: - def __init__(self, iban: str) -> None: - self._iban = iban - - @staticmethod - def fromAddress(address: Union[Address, ChecksumAddress]) -> "Iban": - """ - This method should be used to create - an iban object from ethereum address - - @method fromAddress - @param {String} address - @return {Iban} the IBAN object - """ - validate_address(address) - address_as_integer = int(address, 16) - address_as_base36 = baseN(address_as_integer, 36) - padded = pad_left_hex(address_as_base36, 15) - return Iban.fromBban(padded.upper()) - - @staticmethod - def fromBban(bban: str) -> "Iban": - """ - Convert the passed BBAN to an IBAN for this country specification. - Please note that "generation of the IBAN shall be the exclusive - responsibility of the bank/branch servicing the account". - This method implements the preferred algorithm described in - http://en.wikipedia.org/wiki/International_Bank_Account_Number#Generating_IBAN_check_digits - - @method fromBban - @param {String} bban the BBAN to convert to IBAN - @returns {Iban} the IBAN object - """ - countryCode = "XE" - - remainder = mod9710(iso13616Prepare(countryCode + "00" + bban)) - checkDigit = ("0" + str(98 - remainder))[-2:] - - return Iban(countryCode + checkDigit + bban) - - @staticmethod - def createIndirect(options: IbanOptions) -> "Iban": - """ - Should be used to create IBAN object for given institution and identifier - - @method createIndirect - @param {Object} options, required options are "institution" and "identifier" - @return {Iban} the IBAN object - """ - return Iban.fromBban("ETH" + options["institution"] + options["identifier"]) - - isValid = IsValid() - - def isDirect(self) -> bool: - """ - Should be called to check if iban number is direct - - @method isDirect - @returns {Boolean} true if it is, otherwise false - """ - return len(self._iban) in [34, 35] - - def isIndirect(self) -> bool: - """ - Should be called to check if iban number if indirect - - @method isIndirect - @returns {Boolean} true if it is, otherwise false - """ - return len(self._iban) == 20 - - def checksum(self) -> str: - """ - Should be called to get iban checksum - Uses the mod-97-10 checksumming protocol (ISO/IEC 7064:2003) - - @method checksum - @returns {String} checksum - """ - return self._iban[2:4] - - def institution(self) -> str: - """ - Should be called to get institution identifier - eg. XREG - - @method institution - @returns {String} institution identifier - """ - if self.isIndirect(): - return self._iban[7:11] - else: - return "" - - def client(self) -> str: - """ - Should be called to get client identifier within institution - eg. GAVOFYORK - - @method client - @returns {String} client identifier - """ - if self.isIndirect(): - return self._iban[11:] - else: - return "" - - def address(self) -> Union[str, ChecksumAddress]: - """ - Should be called to get client direct address - - @method address - @returns {String} client direct address - """ - if self.isDirect(): - base36 = self._iban[4:] - asInt = int(base36, 36) - return to_checksum_address(pad_left_hex(baseN(asInt, 16), 20)) - - return "" - - def toString(self) -> str: - return self._iban diff --git a/web3/main.py b/web3/main.py index acbac1b9a3..614f336c6d 100644 --- a/web3/main.py +++ b/web3/main.py @@ -81,9 +81,6 @@ GethPersonal, GethTxPool, ) -from web3.iban import ( - Iban, -) from web3.manager import ( RequestManager as DefaultRequestManager, ) @@ -161,9 +158,6 @@ class Web3: # Managers RequestManager = DefaultRequestManager - # Iban - Iban = Iban - # Encoding and Decoding @staticmethod @wraps(to_bytes)