diff --git a/src/ape/api/transactions.py b/src/ape/api/transactions.py index cffe3346f6..2c227d49b0 100644 --- a/src/ape/api/transactions.py +++ b/src/ape/api/transactions.py @@ -284,11 +284,22 @@ def __ape_extra_attributes__(self) -> Iterator[ExtraModelAttributes]: @field_validator("transaction", mode="before") @classmethod - def confirm_transaction(cls, value): - if isinstance(value, dict): - value = TransactionAPI.model_validate(value) + def _validate_transaction(cls, value): + if not isinstance(value, dict): + # Already a `TransactionAPI`. + return value - return value + # Attempt to create a transaction model for the data. + if provider := cls.network_manager.active_provider: + ecosystem = provider.network.ecosystem + else: + logger.warning( + "Given raw-transaction data when not connected to any provider. " + "Network is unknown. Assuming EVM-like transaction model." + ) + ecosystem = cls.network_manager.ethereum + + return ecosystem.create_transaction(**value) @field_validator("txn_hash", mode="before") @classmethod diff --git a/tests/functional/test_receipt.py b/tests/functional/test_receipt.py index 1b3c5bda3b..7a256cadac 100644 --- a/tests/functional/test_receipt.py +++ b/tests/functional/test_receipt.py @@ -3,7 +3,7 @@ from ape.api import ReceiptAPI from ape.exceptions import APINotImplementedError, ContractLogicError, OutOfGasError from ape.utils import ManagerAccessMixin -from ape_ethereum.transactions import Receipt, TransactionStatusEnum +from ape_ethereum.transactions import DynamicFeeTransaction, Receipt, TransactionStatusEnum @pytest.fixture @@ -198,3 +198,15 @@ def test_track_coverage(deploy_receipt, mocker): def test_access_from_tx(deploy_receipt): actual = deploy_receipt.transaction.receipt assert actual == deploy_receipt + + +def test_transaction_validated_from_dict(ethereum, owner, deploy_receipt): + tx = ethereum.create_transaction(sender=owner.address, value=123, data=b"hello") + tx_data = tx.model_dump() + receipt_data = deploy_receipt.model_dump(by_alias=True) + receipt_data["transaction"] = tx_data + receipt = Receipt.model_validate(receipt_data) + assert isinstance(receipt.transaction, DynamicFeeTransaction) + assert receipt.transaction.sender == owner.address + assert receipt.transaction.value == 123 + assert receipt.transaction.data == b"hello"