Metadata-Version: 2.4
Name: eth-pydantic-types
Version: 0.2.6
Summary: Pydantic Types for Ethereum
Author-email: "ApeWorX Ltd." <admin@apeworx.io>
License-Expression: Apache-2.0
Project-URL: Repository, https://github.com/ApeWorX/eth-pydantic-types
Project-URL: Issues, https://github.com/ApeWorX/eth-pydantic-types/issues
Project-URL: Documentation, https://docs.apeworx.io/eth-pydantic-types
Keywords: ethereum,pydantic,validation
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: Natural Language :: English
Classifier: Operating System :: MacOS
Classifier: Operating System :: POSIX
Classifier: Operating System :: Microsoft :: Windows
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Requires-Python: <4,>=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: hexbytes<2,>=0.3.1
Requires-Dist: eth-utils>=2.3.1
Requires-Dist: eth-typing>=3.5.2
Requires-Dist: pydantic<3,>=2.5.2
Requires-Dist: typing_extensions<5,>=4.8.0
Dynamic: license-file

# eth-pydantic-types

The types in this package are pydantic types for Ethereum inspired from [eth-typing](https://github.com/ethereum/eth-typing/blob/master/eth_typing/evm.py).

## HexStr

When your model involves a string serializes to a hex-str, `HexStr` is the type to use.
Examples of `HexStr` might be a hash.

Use `HexStr` in your models:

```python
from pydantic import BaseModel
from eth_pydantic_types import HexStr, HexStr32

class TransactionData(BaseModel):
    hash_any_size: HexStr
    sized_hash: HexStr32

data = TransactionData(hash_any_size="0x123", sized_hash="0x000123")
assert isinstance(data.nonce, str)
assert isinstance(data.gas, str)
```

## HexBytes

When your model involves bytes that serialize to a hex-str, `HexBytes` is the type to use.
Examples of `HexBytes` might be a hash.

Use `HexBytes` in your models:

```python
from pydantic import BaseModel
from eth_pydantic_types import HexBytes, HexBytes32

class TransactionData(BaseModel):
    hash_any_size: HexBytes
    sized_hash: HexBytes32

data = TransactionData(hash_any_size="0x123", sized_hash="0x000123")
assert isinstance(data.nonce, str)
assert isinstance(data.gas, str)
```

## HexInt

When your model involves an integer that serializes to a hex-str, `HexInt` is the type to use.
Examples of `HexInt` are transaction-type, nonce, and gas values.

Use `HexInt` in your models:

```python
from pydantic import BaseModel
from eth_pydantic_types import HexInt

class TransactionData(BaseModel):
    nonce: HexInt
    gas: HexInt

data = TransactionData(nonce="0x123", gas="0x000123")
assert isinstance(data.nonce, int)
assert isinstance(data.gas, int)
```

## Address

Use the Address class for working with checksummed-addresses.
Addresses get validated and checksummed in model construction.
Addresses serialize to `str` in the Pydantic core schema and `string` in the JSON schema with a binary format.

```python
from pydantic import BaseModel
from eth_pydantic_types import Address

class Account(BaseModel):
    address: Address

# NOTE: The address ends up checksummed
#   ("0x0837207e343277CBd6c114a45EC0e9Ec56a1AD84")
account = Account(address="0x837207e343277cbd6c114a45ec0e9ec56a1ad84")
```

## HexStr

Use hex str when you only care about un-sized hex strings.
The `HexStr` type serializes to `str` in the Pydantic core schema and a `string` in the JSON schema with a binary format.

```python
from eth_pydantic_types import HexStr
from pydantic import BaseModel

class Tx(BaseModel):
    data: HexStr

tx = Tx(data="0x0123")
```

## Bip122Uri

Use BIP-122 URIs in your models by annotating with the `Bip122Uri` type.
This type serializes to a `str` in the Pydantic core schema as well as a `string` in the JSON schema, however the individual hashes are validated.

```python
from eth_pydantic_types import Bip122Uri
from pydantic import BaseModel

class Message(BaseModel):
    path: Bip122Uri

message = Message(
    path=(
        "blockchain://d4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3"
        "/block/752820c0ad7abc1200f9ad42c4adc6fbb4bd44b5bed4667990e64565102c1ba6"
    )
)
```

## Custom Types

You can build your own hex types by subclassing and passing kwargs to the validators.
For example, here is a 32-byte hash type without the `0x` prefix:

```python
from pydantic import BaseModel
from pydantic_core.core_schema import with_info_before_validator_function, str_schema

from eth_pydantic_types import HexStr32


class MyAddress(HexStr32):
    @classmethod
    def __get_pydantic_core_schema__(cls, value, handler=None):
        str_size = cls.size * 2
        return with_info_before_validator_function(
            cls.__eth_pydantic_validate__,
            str_schema(max_length=str_size, min_length=str_size),
        )

    @classmethod
    def __eth_pydantic_validate__(cls, value, info=None, **kwargs):
        return super().__eth_pydantic_validate__(value, info=info, prefixed=False, **kwargs)


class MyModel(BaseModel):
    address: MyAddress

model = MyModel(address="0x" + "ab" * 32)
```

## Padding

For types like `HexStr` or `HexBytes`, you can control the padding by using `@field_validator()`.

```python
from pydantic import BaseModel, field_validator
from eth_pydantic_types import HexStr20, HexBytes20
from eth_pydantic_types.utils import Pad

class MyModel(BaseModel):
    my_str: HexStr20
    my_bytes: HexBytes20

    @field_validator("my_str", "my_bytes", mode="before")
    @classmethod
    def validate_value(cls, value, info):
        field_type = cls.model_fields[info.field_name].annotation
        return field_type.__eth_pydantic_validate__(value, pad=Pad.RIGHT)
```

Else, by default, if you validate integer values, it will pad left.
Other inputs pad right.
This mirrors Solidity types, like `bytes32`, that automatically pad-right when given smaller values.
Integer and address types automatically pad-left.
