Skip to content

Commit

Permalink
feat: add validator for trx addresses (#384)
Browse files Browse the repository at this point in the history
- feat: add validator for trx addresses
- bump version
- fix minor issues in changelog
  • Loading branch information
msamsami authored Jul 4, 2024
1 parent 4973c49 commit 860ca46
Show file tree
Hide file tree
Showing 8 changed files with 144 additions and 4 deletions.
20 changes: 20 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,24 @@ Note to self: Breaking changes must increment either
-->

## 0.30.0 (2024-07-04)

_**Breaking**_

> No breaking changes were introduced in this version.
_**Features**_

- feat: add validator for trx addresses by @msamsami in [#384](https://github.com/python-validators/validators/pull/384)

_**Maintenance**_

- maint: bump version by @msamsami in [#384](https://github.com/python-validators/validators/pull/384)

**Full Changelog**: [`0.29.0...0.30.0`](https://github.com/python-validators/validators/compare/0.29.0...0.30.0)

---

## 0.29.0 (2024-07-01)

_**Breaking**_ ⚠️
Expand All @@ -25,6 +43,8 @@ _**Maintenance**_

**Full Changelog**: [`0.28.3...0.29.0`](https://github.com/python-validators/validators/compare/0.28.3...0.29.0)

---

## 0.28.3 (2024-05-25)

_**Breaking**_
Expand Down
2 changes: 1 addition & 1 deletion SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

| Version | Supported |
| ---------- | ------------------ |
| `>=0.29.0` | :white_check_mark: |
| `>=0.30.0` | :white_check_mark: |

## Reporting a Vulnerability

Expand Down
1 change: 1 addition & 0 deletions docs/api/crypto_addresses.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@

::: validators.crypto_addresses.btc_address
::: validators.crypto_addresses.eth_address
::: validators.crypto_addresses.trx_address
1 change: 1 addition & 0 deletions docs/api/crypto_addresses.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ crypto_addresses
.. module:: validators.crypto_addresses
.. autofunction:: btc_address
.. autofunction:: eth_address
.. autofunction:: trx_address
5 changes: 3 additions & 2 deletions src/validators/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from .card import amex, card_number, diners, discover, jcb, mastercard, unionpay, visa
from .country import calling_code, country_code, currency
from .cron import cron
from .crypto_addresses import btc_address, eth_address
from .crypto_addresses import btc_address, eth_address, trx_address
from .domain import domain
from .email import email
from .encoding import base58, base64
Expand Down Expand Up @@ -39,6 +39,7 @@
# crypto_addresses
"btc_address",
"eth_address",
"trx_address",
# cards
"amex",
"card_number",
Expand Down Expand Up @@ -104,4 +105,4 @@
"validator",
)

__version__ = "0.29.0"
__version__ = "0.30.0"
3 changes: 2 additions & 1 deletion src/validators/crypto_addresses/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@
# local
from .btc_address import btc_address
from .eth_address import eth_address
from .trx_address import trx_address

__all__ = ("btc_address", "eth_address")
__all__ = ("btc_address", "eth_address", "trx_address")
62 changes: 62 additions & 0 deletions src/validators/crypto_addresses/trx_address.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
"""TRX Address."""

# standard
import hashlib
import re

# local
from validators.utils import validator


def _base58_decode(addr: str) -> bytes:
"""Decode a base58 encoded address."""
alphabet = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
num = 0
for char in addr:
num = num * 58 + alphabet.index(char)
return num.to_bytes(25, byteorder="big")


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

try:
address = _base58_decode(addr)
except ValueError:
return False

if len(address) != 25 or address[0] != 0x41:
return False

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


@validator
def trx_address(value: str, /):
"""Return whether or not given value is a valid tron address.
Full validation is implemented for TRC20 tron addresses.
Examples:
>>> trx_address('TLjfbTbpZYDQ4EoA4N5CLNgGjfbF8ZWz38')
# Output: True
>>> trx_address('TR2G7Rm4vFqF8EpY4U5xdLdQ7XgJ2U8Vd')
# Output: ValidationError(func=trx_address, args=...)
Args:
value:
Tron address string to validate.
Returns:
(Literal[True]): If `value` is a valid tron address.
(ValidationError): If `value` is an invalid tron address.
"""
if not value:
return False

return re.compile(r"^[T][a-km-zA-HJ-NP-Z1-9]{33}$").match(
value
) and _validate_trx_checksum_address(value)
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."""

# external
import pytest

# local
from validators import ValidationError, trx_address


@pytest.mark.parametrize(
"value",
[
"TLjfbTbpZYDQ4EoA4N5CLNgGjfbF8ZWz38",
"TDQ6C92wuNqvMWE967sMptCFaXq77uj1PF",
"TFuGbxCQGSL4oLnJzVsen844LDwFbrUY4e",
"TFAPKADDRhkSe3v27CsR8TZSjN8eJ8ycDK",
"TSJHywLNva2MNjCD5iYfn5QAKD9Rk5Ncit",
"TEi1qhi5LuTicg1u9oAstyXCSf5uibSyqo",
"TAGvx5An6VBeHTu91cQwdABNcAYMRPcP4n",
"TXbE5tXTejqT3Q47sYKCDb9NJDm3xrFpab",
"TMTxQWNuWHXvHcYXc5D1wQhFmZFJijAxcG",
"TPHgw9E8QYM3esNWih5KVnUVpUHwLTPfpA",
"TFFLtBTi9jdaGwV3hznjCmPYaJme5AeqwU",
"TC74QG8tbtixG5Raa4fEifywgjrFs45fNz",
],
)
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), ValidationError)

0 comments on commit 860ca46

Please sign in to comment.