diff --git a/crypto/utils/unit_converter.py b/crypto/utils/unit_converter.py new file mode 100644 index 00000000..39688849 --- /dev/null +++ b/crypto/utils/unit_converter.py @@ -0,0 +1,60 @@ +# import numpy as np +from decimal import Decimal +from typing import Union + +class UnitConverter: + WEI_MULTIPLIER = '1' + GWEI_MULTIPLIER = '1000000000' # 1e9 + ARK_MULTIPLIER = '1000000000000000000' # 1e18 + + @staticmethod + def parse_units(value: Union[float, int, str, Decimal], unit='ark') -> str: + value = Decimal(str(value)) + + unit = unit.lower() + if unit == 'wei': + return format((value * Decimal(UnitConverter.WEI_MULTIPLIER)).normalize(), 'f') + + if unit == 'gwei': + return format((value * Decimal(UnitConverter.GWEI_MULTIPLIER)).normalize(), 'f') + + if unit == 'ark': + return format((value * Decimal(UnitConverter.ARK_MULTIPLIER)).normalize(), 'f') + + raise ValueError(f"Unsupported unit: {unit}. Supported units are 'wei', 'gwei', and 'ark'.") + + @staticmethod + def format_units(value: Union[float, int, str, Decimal], unit='ark') -> Decimal: + value = Decimal(str(value)) + + unit = unit.lower() + if unit == 'wei': + return value / Decimal(UnitConverter.WEI_MULTIPLIER) + + if unit == 'gwei': + return value / Decimal(UnitConverter.GWEI_MULTIPLIER) + + if unit == 'ark': + return value / Decimal(UnitConverter.ARK_MULTIPLIER) + + raise ValueError(f"Unsupported unit: {unit}. Supported units are 'wei', 'gwei', and 'ark'.") + + @staticmethod + def wei_to_ark(value: Union[float, int, str, Decimal], suffix=None): + converted_value = UnitConverter.format_units(UnitConverter.parse_units(value, 'wei'), 'ark') + converted_value = format(converted_value.normalize(), 'f') + + if suffix is not None: + return f"{converted_value} {suffix}" + + return str(converted_value) + + @staticmethod + def gwei_to_ark(value: Union[float, int, str, Decimal], suffix=None): + converted_value = UnitConverter.format_units(UnitConverter.parse_units(value, 'gwei'), 'ark') + converted_value = format(converted_value.normalize(), 'f') + + if suffix is not None: + return f"{converted_value} {suffix}" + + return str(converted_value) diff --git a/tests/utils/test_unit_converter.py b/tests/utils/test_unit_converter.py new file mode 100644 index 00000000..64886b12 --- /dev/null +++ b/tests/utils/test_unit_converter.py @@ -0,0 +1,122 @@ +from crypto.utils.unit_converter import UnitConverter +from decimal import Decimal + +def test_it_should_parse_units_into_wei(): + assert UnitConverter.parse_units(1, 'wei') == '1' + assert UnitConverter.parse_units(1.0, 'wei') == '1' + assert UnitConverter.parse_units('1', 'wei') == '1' + assert UnitConverter.parse_units('1.0', 'wei') == '1' + + assert UnitConverter.parse_units(Decimal(1), 'wei') == '1' + assert UnitConverter.parse_units(Decimal(1.0), 'wei') == '1' + assert UnitConverter.parse_units(Decimal('1'), 'wei') == '1' + assert UnitConverter.parse_units(Decimal('1.0'), 'wei') == '1' + +def test_it_should_parse_units_into_gwei(): + assert UnitConverter.parse_units(1, 'gwei') == '1000000000' + assert UnitConverter.parse_units(1.0, 'gwei') == '1000000000' + assert UnitConverter.parse_units('1', 'gwei') == '1000000000' + assert UnitConverter.parse_units('1.0', 'gwei') == '1000000000' + + assert UnitConverter.parse_units(Decimal(1), 'gwei') == '1000000000' + assert UnitConverter.parse_units(Decimal(1.0), 'gwei') == '1000000000' + assert UnitConverter.parse_units(Decimal('1'), 'gwei') == '1000000000' + assert UnitConverter.parse_units(Decimal('1.0'), 'gwei') == '1000000000' + +def test_it_should_parse_units_into_ark(): + assert UnitConverter.parse_units(1, 'ark') == '1000000000000000000' + assert UnitConverter.parse_units(1.0, 'ark') == '1000000000000000000' + assert UnitConverter.parse_units('1', 'ark') == '1000000000000000000' + assert UnitConverter.parse_units('1.0', 'ark') == '1000000000000000000' + + assert UnitConverter.parse_units(Decimal(1), 'ark') == '1000000000000000000' + assert UnitConverter.parse_units(Decimal(1.0), 'ark') == '1000000000000000000' + assert UnitConverter.parse_units(Decimal('1'), 'ark') == '1000000000000000000' + assert UnitConverter.parse_units(Decimal('1.0'), 'ark') == '1000000000000000000' + +def test_it_should_parse_decimal_units_into_ark(): + assert UnitConverter.parse_units(0.1, 'ark') == '100000000000000000' + assert UnitConverter.parse_units('0.1', 'ark') == '100000000000000000' + +def test_it_should_format_units_from_wei(): + assert UnitConverter.format_units(1, 'wei') == 1.0 + assert UnitConverter.format_units(1.0, 'wei') == 1.0 + assert UnitConverter.format_units('1', 'wei') == 1.0 + assert UnitConverter.format_units('1.0', 'wei') == 1.0 + + assert UnitConverter.format_units(Decimal(1), 'wei') == 1.0 + assert UnitConverter.format_units(Decimal(1.0), 'wei') == 1.0 + assert UnitConverter.format_units(Decimal('1'), 'wei') == 1.0 + assert UnitConverter.format_units(Decimal('1.0'), 'wei') == 1.0 + +def test_it_should_format_units_from_gwei(): + assert UnitConverter.format_units(1000000000, 'gwei') == 1.0 + assert UnitConverter.format_units('1000000000', 'gwei') == 1.0 + + assert UnitConverter.format_units(Decimal(1000000000), 'gwei') == 1.0 + assert UnitConverter.format_units(Decimal('1000000000'), 'gwei') == 1.0 + +def test_it_should_format_units_from_ark(): + assert UnitConverter.format_units(1000000000000000000, 'ark') == 1.0 + assert UnitConverter.format_units('1000000000000000000', 'ark') == 1.0 + + assert UnitConverter.format_units(Decimal(1000000000000000000), 'ark') == 1.0 + assert UnitConverter.format_units(Decimal('1000000000000000000'), 'ark') == 1.0 + +def test_it_should_throw_exception_for_unsupported_unit_in_parse(): + try: + UnitConverter.parse_units(1, 'unsupported') + except ValueError as e: + assert str(e) == 'Unsupported unit: unsupported. Supported units are \'wei\', \'gwei\', and \'ark\'.' + +def test_it_should_throw_exception_for_unsupported_unit_in_format(): + try: + UnitConverter.format_units('1', 'unsupported') + except ValueError as e: + assert str(e) == 'Unsupported unit: unsupported. Supported units are \'wei\', \'gwei\', and \'ark\'.' + +def test_it_should_parse_units_into_ark_with_fraction(): + assert UnitConverter.parse_units(0.1, 'ark') == '100000000000000000' + assert UnitConverter.parse_units('0.1', 'ark') == '100000000000000000' + +def test_it_should_convert_wei_to_ark(): + assert UnitConverter.wei_to_ark(1, 'DARK') == '0.000000000000000001 DARK' + assert UnitConverter.wei_to_ark(1) == '0.000000000000000001' + assert UnitConverter.wei_to_ark(1000000000000000000, 'DARK') == '1 DARK' + assert UnitConverter.wei_to_ark(1000000000000000000) == '1' + + assert UnitConverter.wei_to_ark('1', 'DARK') == '0.000000000000000001 DARK' + assert UnitConverter.wei_to_ark('1') == '0.000000000000000001' + assert UnitConverter.wei_to_ark('1000000000000000000', 'DARK') == '1 DARK' + assert UnitConverter.wei_to_ark('1000000000000000000') == '1' + + assert UnitConverter.wei_to_ark(Decimal(1), 'DARK') == '0.000000000000000001 DARK' + assert UnitConverter.wei_to_ark(Decimal(1)) == '0.000000000000000001' + assert UnitConverter.wei_to_ark(Decimal(1000000000000000000), 'DARK') == '1 DARK' + assert UnitConverter.wei_to_ark(Decimal(1000000000000000000)) == '1' + + assert UnitConverter.wei_to_ark(Decimal('1'), 'DARK') == '0.000000000000000001 DARK' + assert UnitConverter.wei_to_ark(Decimal('1')) == '0.000000000000000001' + assert UnitConverter.wei_to_ark(Decimal('1000000000000000000'), 'DARK') == '1 DARK' + assert UnitConverter.wei_to_ark(Decimal('1000000000000000000')) == '1' + +def test_it_should_convert_gwei_to_ark(): + assert UnitConverter.gwei_to_ark(1, 'DARK') == '0.000000001 DARK' + assert UnitConverter.gwei_to_ark(1) == '0.000000001' + assert UnitConverter.gwei_to_ark(1000000000, 'DARK') == '1 DARK' + assert UnitConverter.gwei_to_ark(1000000000) == '1' + + assert UnitConverter.gwei_to_ark('1', 'DARK') == '0.000000001 DARK' + assert UnitConverter.gwei_to_ark('1') == '0.000000001' + assert UnitConverter.gwei_to_ark('1000000000', 'DARK') == '1 DARK' + assert UnitConverter.gwei_to_ark('1000000000') == '1' + + assert UnitConverter.gwei_to_ark(Decimal(1), 'DARK') == '0.000000001 DARK' + assert UnitConverter.gwei_to_ark(Decimal(1)) == '0.000000001' + assert UnitConverter.gwei_to_ark(Decimal(1000000000), 'DARK') == '1 DARK' + assert UnitConverter.gwei_to_ark(Decimal(1000000000)) == '1' + + assert UnitConverter.gwei_to_ark(Decimal('1'), 'DARK') == '0.000000001 DARK' + assert UnitConverter.gwei_to_ark(Decimal('1')) == '0.000000001' + assert UnitConverter.gwei_to_ark(Decimal('1000000000'), 'DARK') == '1 DARK' + assert UnitConverter.gwei_to_ark(Decimal('1000000000')) == '1'