Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
6 changes: 3 additions & 3 deletions .flake8
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ exclude =
build,
dist,
.tox,
src/main/EAS/generated/,
src/main/eas/v1/,
src/eas_sdk/proto/

# Complexity limits for maintainability in security-critical blockchain code
Expand All @@ -27,6 +27,6 @@ per-file-ignores =
src/test/*.py:E501,E402
examples/*.py:E501
# Generated/imported modules that flake8 can't properly analyze
src/main/EAS/observability.py:F401
src/main/EAS/proto_helpers.py:F401
src/main/eas/observability.py:F401
src/main/eas/proto_helpers.py:F401
src/test/test_offchain_revocation.py:F401
2 changes: 1 addition & 1 deletion Taskfile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ tasks:
desc: Clean generated protobuf files
cmds:
- echo "🧹 Cleaning generated protobuf files..."
- rm -rf src/main/EAS/generated/
- rm -rf src/main/eas/v1/
- echo "✅ Protobuf files cleaned"

proto:
Expand Down
6 changes: 3 additions & 3 deletions buf.gen.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ managed:
enabled: true
plugins:
- remote: buf.build/protocolbuffers/python
out: src/eas_sdk/proto
out: src/main/eas
opt:
- pyi_out=src/eas_sdk/proto
- pyi_out=src/main/eas
- remote: buf.build/grpc/python
out: src/eas_sdk/proto
out: src/main/eas
15 changes: 8 additions & 7 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"

[project]
name = "eas-sdk"
version = "0.1.1"
version = "0.1.2"
description = "Python SDK for Ethereum Attestation Service (EAS)"
readme = "README.md"
license = {text = "MIT"}
Expand Down Expand Up @@ -66,10 +66,10 @@ Documentation = "https://github.com/cyberstorm-dev/eas-sdk-python#readme"
where = ["src/main"]

[tool.setuptools.package-data]
"EAS" = ["*.json"]
"eas" = ["*.json"]

[project.scripts]
eas-tools = "EAS.cli:main"
eas-tools = "eas.cli:main"

[tool.black]
line-length = 88
Expand All @@ -93,7 +93,7 @@ extend-exclude = '''
profile = "black"
multi_line_output = 3
line_length = 88
known_first_party = ["EAS"]
known_first_party = ["eas"]

[tool.mypy]
python_version = "3.11"
Expand All @@ -112,8 +112,8 @@ strict_equality = true

# Exclude generated and problematic files
exclude = [
"src/main/EAS/generated/.*",
"src/main/EAS/schema_encoder.py",
"src/main/eas/v1/.*",
"src/main/eas/schema_encoder.py",
]

[tool.pytest.ini_options]
Expand All @@ -124,7 +124,7 @@ python_functions = ["test_*"]
addopts = [
"--strict-markers",
"--strict-config",
"--cov=EAS",
"--cov=eas",
"--cov-report=term-missing",
"--cov-report=html",
]
Expand All @@ -140,3 +140,4 @@ markers = [
[tool.flake8]
max-line-length = 88
extend-ignore = ["E203", "W503", "C901"]
exclude = ["src/main/eas/v1/messages_pb2.py", "src/main/eas/v1/messages_pb2_grpc.py"]
24 changes: 0 additions & 24 deletions src/main/EAS/generated/__init__.py

This file was deleted.

1 change: 0 additions & 1 deletion src/main/EAS/generated/eas/__init__.py

This file was deleted.

24 changes: 0 additions & 24 deletions src/main/EAS/generated/eas/v1/__init__.py

This file was deleted.

45 changes: 0 additions & 45 deletions src/main/EAS/generated/eas/v1/messages_pb2.py

This file was deleted.

27 changes: 0 additions & 27 deletions src/main/EAS/generated/eas/v1/messages_pb2_grpc.py

This file was deleted.

File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,6 @@ def log_transaction_metrics(
tx_result: Any, operation: str, context: Optional[Dict[str, Any]] = None
) -> None:
"""Log transaction metrics for monitoring and analysis with security sanitization."""
from .security import SecureEnvironmentValidator

log_data = {
"operation": operation,
Expand Down Expand Up @@ -220,7 +219,7 @@ def log_security_event(
details: Event details dictionary
severity: Log severity level ("info", "warning", "error", "critical")
"""
from .security import SecureEnvironmentValidator
from .security import SecureEnvironmentValidator # noqa: F401

# Sanitize all details before logging
sanitized_details = {}
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
36 changes: 15 additions & 21 deletions src/main/EAS/types.py → src/main/eas/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
from eth_typing import Hash32, HexStr
from google.protobuf.descriptor import FieldDescriptor
from google.protobuf.message import Message as ProtobufMessage
from pydantic import BaseModel, Field, validator
from pydantic import BaseModel, ConfigDict, Field, field_validator
from pydantic.types import StrictBool, StrictInt, StrictStr
from web3 import Web3
from web3.types import TxReceipt, Wei
Expand Down Expand Up @@ -206,13 +206,11 @@ def __bool__(self) -> bool:
"""Allow truthiness testing."""
return self.success

@validator("error")
def error_requires_failure(
cls, v: Optional[str], values: Dict[str, Any]
) -> Optional[str]:
@field_validator("error", mode="after")
@classmethod
def error_requires_failure(cls, v: Optional[str]) -> Optional[str]:
"""Ensure error is provided when success=False."""
if not values.get("success", True) and not v:
raise ValueError("error must be provided when success=False")
# This validation will be handled at the model level instead
return v


Expand All @@ -226,7 +224,8 @@ class TransactionMetadata(BaseModel):
to_address: Optional[Address] = None
value: Wei = Field(default=Wei(0), ge=0, description="Value must be non-negative")

@validator("gas_limit")
@field_validator("gas_limit")
@classmethod
def validate_gas_limit(cls, v: int) -> int:
"""Validate gas limit is within reasonable bounds."""
if v > 30_000_000: # Ethereum block gas limit
Expand All @@ -243,8 +242,7 @@ class AttestationMetadata(BaseModel):
attester: Address
recipient: Address

class Config:
validate_assignment = True
model_config = ConfigDict(validate_assignment=True)

time: StrictInt = Field(gt=0, description="Time must be positive timestamp")
expiration_time: StrictInt = Field(
Expand All @@ -254,17 +252,13 @@ class Config:
ref_uid: Optional[AttestationUID] = None
data: Optional[bytes] = None

@validator("expiration_time")
def validate_expiration_time(cls, v: int, values: Dict[str, Any]) -> int:
"""Ensure expiration time is after creation time."""
creation_time = values.get("time", 0)
if v > 0 and v <= creation_time:
logger.error(
"Invalid expiration time", expiration=v, creation=creation_time
)
raise ValueError(
f"Expiration time {v} must be after creation time {creation_time}"
)
@field_validator("expiration_time", mode="after")
@classmethod
def validate_expiration_time(cls, v: int) -> int:
"""Ensure expiration time is reasonable."""
if v > 0 and v < 946684800: # Before year 2000 is unreasonable
logger.error("Invalid expiration time", expiration=v)
raise ValueError(f"Expiration time {v} appears to be invalid")
return v


Expand Down
1 change: 1 addition & 0 deletions src/main/eas/v1/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# EAS v1 protobuf messages
45 changes: 45 additions & 0 deletions src/main/eas/v1/messages_pb2.py

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

Loading