Skip to content

Move btc validator to crypto addresses submodule #278

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 40 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
504d092
add validator for eth addresses
msamsami Jun 11, 2023
cef562c
add test for eth address validator
msamsami Jun 11, 2023
498166c
add pysha3 dependency
msamsami Jun 11, 2023
ef43f0a
add validator for trx addresses
msamsami Jun 11, 2023
2094e29
add unit test for trx address validator
msamsami Jun 11, 2023
95047c3
add base58 dependency
msamsami Jun 11, 2023
1892a77
change an invalid trx address
msamsami Jun 11, 2023
dd65e7c
minor change in docstrings
msamsami Jun 11, 2023
5592922
move trx validator to a submodule
msamsami Jun 12, 2023
3f1d368
move trx validator tests to a submodule
msamsami Jun 12, 2023
02267c3
move eth and btc validators to a new submodule
msamsami Jun 12, 2023
8a66692
move eth and btc validators' tests to a new submodule
msamsami Jun 12, 2023
875dcd3
add init files for new submodules
msamsami Jun 12, 2023
fbd43f8
add btc and eth validators to init
msamsami Jun 12, 2023
ec1071f
add trx validator to init
msamsami Jun 12, 2023
11ee0e1
fix bug in importing validator
msamsami Jun 12, 2023
a3b7367
revert moving btc validator and its tests to new submodules
msamsami Jun 12, 2023
9345ae4
remove btc validator from init
msamsami Jun 12, 2023
80c8fb9
move btc estimator and its test to crypto addresses submodules
msamsami Jun 12, 2023
a97c5d1
fix import
msamsami Jun 12, 2023
d0a1eac
remove faulty test value
msamsami Jun 17, 2023
e4128c9
use relative import
msamsami Jun 17, 2023
1715ea3
remove trx_validator
msamsami Jun 17, 2023
8be96ea
fix bugs in test values
msamsami Jun 17, 2023
8f2e253
combine eth regex checks into one check
msamsami Jun 17, 2023
04d9b8b
check length in checksum validation
msamsami Jun 17, 2023
989d262
add validator for trx addresses
msamsami Jun 11, 2023
657f7c6
add unit test for trx address validator
msamsami Jun 11, 2023
2ad4424
add base58 dependency
msamsami Jun 11, 2023
9dd10b1
change an invalid trx address
msamsami Jun 11, 2023
0369ab1
minor change in docstrings
msamsami Jun 11, 2023
7e01538
rebase with parent branch
msamsami Jun 12, 2023
49fa8e6
move trx validator tests to a submodule
msamsami Jun 12, 2023
d35aceb
add btc and eth validators to init
msamsami Jun 12, 2023
472518d
remove btc validator from init
msamsami Jun 12, 2023
8a8df90
Merge branch 'add-trx-validator' of github.com:msamsami/validators in…
msamsami Jun 17, 2023
9b29318
use relative import
msamsami Jun 17, 2023
4d9904f
move btc estimator and its test to crypto addresses submodules
msamsami Jun 12, 2023
1d57065
Merge branch 'move-btc-validator' of github.com:msamsami/validators i…
msamsami Jun 17, 2023
27c6d70
use relative import
msamsami Jun 17, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions tests/crypto_addresses/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
"""Test crypto addresses."""
# -*- coding: utf-8 -*-

# isort: skip_file
File renamed without changes.
45 changes: 45 additions & 0 deletions tests/crypto_addresses/test_eth_address.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
"""Test ETH address."""
# -*- coding: utf-8 -*-

# external
import pytest

# local
from validators import eth_address, ValidationFailure


@pytest.mark.parametrize(
"value",
[
"0x8ba1f109551bd432803012645ac136ddd64dba72",
"0x9cc14ba4f9f68ca159ea4ebf2c292a808aaeb598",
"0x5AEDA56215b167893e80B4fE645BA6d5Bab767DE",
"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
"0x742d35Cc6634C0532925a3b844Bc454e4438f44e",
"0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984",
"0x1234567890123456789012345678901234567890",
"0x57Ab1ec28D129707052df4dF418D58a2D46d5f51",
],
)
def test_returns_true_on_valid_eth_address(value: str):
"""Test returns true on valid eth address."""
assert eth_address(value)


@pytest.mark.parametrize(
"value",
[
"0x742d35Cc6634C0532925a3b844Bc454e4438f44g",
"0x742d35Cc6634C0532925a3b844Bc454e4438f44",
"0xAbcdefg1234567890Abcdefg1234567890Abcdefg",
"0x7c8EE9977c6f96b6b9774b3e8e4Cc9B93B12b2c72",
"0x80fBD7F8B3f81D0e1d6EACAb69AF104A6508AFB1",
"0x7c8EE9977c6f96b6b9774b3e8e4Cc9B93B12b2c7g",
"0x7c8EE9977c6f96b6b9774b3e8e4Cc9B93B12b2c",
"0x7Fb21a171205f3B8d8E4d88A2d2f8A56E45DdB5c",
"validators.eth",
],
)
def test_returns_failed_validation_on_invalid_eth_address(value: str):
"""Test returns failed validation on invalid eth address."""
assert isinstance(eth_address(value), ValidationFailure)
54 changes: 54 additions & 0 deletions tests/crypto_addresses/test_trx_address.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
"""Test TRX address."""
# -*- coding: utf-8 -*-

# external
import pytest

# local
from validators import trx_address, ValidationFailure


@pytest.mark.parametrize(
"value",
[
"TLjfbTbpZYDQ4EoA4N5CLNgGjfbF8ZWz38",
"TDQ6C92wuNqvMWE967sMptCFaXq77uj1PF",
"TFuGbxCQGSL4oLnJzVsen844LDwFbrUY4e",
"TFAPKADDRhkSe3v27CsR8TZSjN8eJ8ycDK",
"TSJHywLNva2MNjCD5iYfn5QAKD9Rk5Ncit",
"TEi1qhi5LuTicg1u9oAstyXCSf5uibSyqo",
"TAGvx5An6VBeHTu91cQwdABNcAYMRPcP4n",
"TXbE5tXTejqT3Q47sYKCDb9NJDm3xrFpab",
"TMTxQWNuWHXvHcYXc5D1wQhFmZFJijAxcG",
"TPHgw9E8QYM3esNWih5KVnUVpUHwLTPfpA",
"TFFLtBTi9jdaGwV3hznjCmPYaJme5AeqwU",
],
)
def test_returns_true_on_valid_trx_address(value: str):
"""Test returns true on valid trx address."""
assert trx_address(value)


@pytest.mark.parametrize(
"value",
[
"T12345678901234567890123456789012345",
"ABCDEFGHIJKLMNOPQRSTUVWXYZ12345678",
"TR2G7Rm4vFqF8EpY4U5xdLdQ7XgJ2U8Vd",
"TP6ah2v5mdsj8Z3hGz1yDMvDq7BzEbK8o",
"TQmmhp6uz2Xre8yL3FsPYZyo4mhtw4vg4XX",
"TQNy2C6VHJPk4P32bsEX3QSGx2Qqm4J2k9",
"TP6ah2v5mdsj8Z3hGz1yDMvDq7BzEbK8oN",
"TSTVdfU1x4L7K3Bc3v5C28Gp2J1rPyeL3f",
"THPByuCzvU5QER9j2NC2mUQ2JPyRCam4e7",
"TW5eZqUZgdW4rxFKAKsc2ryJbfFA94WXvD",
"TR2G7Rm4vFqF8EpY4U5xdLdQ7XgJ2U8Vdd",
"tQmmhp6uz2Xre8yL3FsPYZyo4mhtw4vg4X",
"TR2G7Rm4vFqF8EpY4U5xdLdQ7Xg",
"TQmmhp6uz2Xre8yL3FsPYZyo4mhtw4vg4x",
"my-trox-address.trx"
],
)
def test_returns_failed_validation_on_invalid_trx_address(value: str):
"""Test returns failed validation on invalid trx address."""
assert isinstance(trx_address(value), ValidationFailure)
4 changes: 3 additions & 1 deletion validators/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@

# local
from .between import between
from .btc_address import btc_address
from .card import amex, card_number, diners, discover, jcb, mastercard, unionpay, visa
from .domain import domain
from .email import email
Expand All @@ -24,12 +23,14 @@
from .utils import validator, ValidationFailure
from .uuid import uuid

from .crypto_addresses import btc_address, eth_address, trx_address
from .i18n import es_cif, es_doi, es_nie, es_nif, fi_business_id, fi_ssn

__all__ = (
"amex",
"between",
"btc_address",
"eth_address",
"card_number",
"diners",
"discover",
Expand All @@ -49,6 +50,7 @@
"sha256",
"sha512",
"slug",
"trx_address",
"unionpay",
"url",
"uuid",
Expand Down
11 changes: 11 additions & 0 deletions validators/crypto_addresses/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
"""Crypto addresses."""
# -*- coding: utf-8 -*-

# isort: skip_file

# local
from .btc_address import btc_address
from .eth_address import eth_address
from .trx_address import trx_address

__all__ = ("btc_address", "eth_address", "trx_address")
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import re

# local
from .utils import validator
from validators.utils import validator


def _decode_base58(addr: str):
Expand Down
57 changes: 57 additions & 0 deletions validators/crypto_addresses/eth_address.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
"""ETH Address."""
# -*- coding: utf-8 -*-

# standard
import re

from sha3 import keccak_256

# local
from validators.utils import validator


def _validate_eth_checksum_address(addr: str):
"""Validate ETH type checksum address."""
addr = addr.replace("0x", "")
addr_hash = keccak_256(addr.lower().encode("ascii")).hexdigest()

if len(addr) != 40:
return False

for i in range(0, 40):
if ((int(addr_hash[i], 16) > 7 and addr[i].upper() != addr[i]) or
(int(addr_hash[i], 16) <= 7 and addr[i].lower() != addr[i])):
return False
return True


@validator
def eth_address(value: str, /):
"""Return whether or not given value is a valid ethereum address.

Full validation is implemented for ERC20 addresses.

Examples:
>>> eth_address('0x9cc14ba4f9f68ca159ea4ebf2c292a808aaeb598')
# Output: True
>>> eth_address('0x8Ba1f109551bD432803012645Ac136ddd64DBa72')
# Output: ValidationFailure(func=eth_address, args=...)

Args:
value:
Ethereum address string to validate.

Returns:
(Literal[True]):
If `value` is a valid ethereum address.
(ValidationFailure):
If `value` is an invalid ethereum address.

"""
if not value:
return False

return (
re.compile(r"^0x[0-9a-f]{40}$|^0x[0-9A-F]{40}$").match(value) or
_validate_eth_checksum_address(value)
)
60 changes: 60 additions & 0 deletions validators/crypto_addresses/trx_address.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
"""TRX Address."""
# -*- coding: utf-8 -*-

# standard
from _sha256 import sha256
import re

import base58

# local
from validators.utils import validator


def _validate_trx_checksum_address(addr: str):
"""Validate TRX type checksum address."""
if len(addr) != 34:
return False

address = base58.b58decode(addr)
if len(address) != 25:
return False

if address[0] != 0x41:
return False

check_sum = sha256(sha256(address[:-4]).digest()).digest()[:4]
if address[-4:] == check_sum:
return True


@validator
def trx_address(value: str, /):
"""Return whether or not given value is a valid tron (trx) address.

Full validation is implemented for TRC20 tron addresses.

Examples:
>>> trx_address('TLjfbTbpZYDQ4EoA4N5CLNgGjfbF8ZWz38')
# Output: True
>>> trx_address('TR2G7Rm4vFqF8EpY4U5xdLdQ7XgJ2U8Vd')
# Output: ValidationFailure(func=trx_address, args=...)

Args:
value:
Tron address string to validate.

Returns:
(Literal[True]):
If `value` is a valid tron address.
(ValidationFailure):
If `value` is an invalid tron address.

"""
if not value:
return False

return (
re.compile(r"^(T|41)[a-zA-Z0-9]{33}$").match(value) and
_validate_trx_checksum_address(value)
)