From cb82eb1bc6b72b984fbd12c5f5173c385fbc5d8f Mon Sep 17 00:00:00 2001 From: rohan-agarwal-coinbase Date: Thu, 17 Oct 2024 10:38:41 -0400 Subject: [PATCH 1/2] feat(PSDK-584): Read contract support (#29) --- CHANGELOG.md | 4 + cdp/client/__init__.py | 2 + cdp/client/api/smart_contracts_api.py | 303 ++++ cdp/client/models/__init__.py | 2 + cdp/client/models/read_contract_request.py | 91 ++ cdp/client/models/solidity_value.py | 109 ++ cdp/client/models/update_webhook_request.py | 2 +- cdp/smart_contract.py | 84 ++ tests/factories/smart_contract_factory.py | 800 +++++++++++ tests/test_smart_contract.py | 1383 +++++++++++++++++++ 10 files changed, 2779 insertions(+), 1 deletion(-) create mode 100644 cdp/client/models/read_contract_request.py create mode 100644 cdp/client/models/solidity_value.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 6ce6eec..a569d16 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +### Added + +- Support for read_contract to read from smart contracts + ## [0.0.5] - 2024-10-3 ### Added diff --git a/cdp/client/__init__.py b/cdp/client/__init__.py index 8b003f5..018445d 100644 --- a/cdp/client/__init__.py +++ b/cdp/client/__init__.py @@ -98,6 +98,7 @@ from cdp.client.models.network_identifier import NetworkIdentifier from cdp.client.models.payload_signature import PayloadSignature from cdp.client.models.payload_signature_list import PayloadSignatureList +from cdp.client.models.read_contract_request import ReadContractRequest from cdp.client.models.seed_creation_event import SeedCreationEvent from cdp.client.models.seed_creation_event_result import SeedCreationEventResult from cdp.client.models.server_signer import ServerSigner @@ -112,6 +113,7 @@ from cdp.client.models.smart_contract_list import SmartContractList from cdp.client.models.smart_contract_options import SmartContractOptions from cdp.client.models.smart_contract_type import SmartContractType +from cdp.client.models.solidity_value import SolidityValue from cdp.client.models.sponsored_send import SponsoredSend from cdp.client.models.staking_balance import StakingBalance from cdp.client.models.staking_context import StakingContext diff --git a/cdp/client/api/smart_contracts_api.py b/cdp/client/api/smart_contracts_api.py index a507b57..db0c90f 100644 --- a/cdp/client/api/smart_contracts_api.py +++ b/cdp/client/api/smart_contracts_api.py @@ -20,8 +20,10 @@ from typing_extensions import Annotated from cdp.client.models.create_smart_contract_request import CreateSmartContractRequest from cdp.client.models.deploy_smart_contract_request import DeploySmartContractRequest +from cdp.client.models.read_contract_request import ReadContractRequest from cdp.client.models.smart_contract import SmartContract from cdp.client.models.smart_contract_list import SmartContractList +from cdp.client.models.solidity_value import SolidityValue from cdp.client.api_client import ApiClient, RequestSerialized from cdp.client.api_response import ApiResponse @@ -1217,3 +1219,304 @@ def _list_smart_contracts_serialize( ) + + + @validate_call + def read_contract( + self, + network_id: StrictStr, + contract_address: StrictStr, + read_contract_request: ReadContractRequest, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> SolidityValue: + """Read data from a smart contract + + Perform a read operation on a smart contract without creating a transaction + + :param network_id: (required) + :type network_id: str + :param contract_address: (required) + :type contract_address: str + :param read_contract_request: (required) + :type read_contract_request: ReadContractRequest + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._read_contract_serialize( + network_id=network_id, + contract_address=contract_address, + read_contract_request=read_contract_request, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "SolidityValue", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + def read_contract_with_http_info( + self, + network_id: StrictStr, + contract_address: StrictStr, + read_contract_request: ReadContractRequest, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[SolidityValue]: + """Read data from a smart contract + + Perform a read operation on a smart contract without creating a transaction + + :param network_id: (required) + :type network_id: str + :param contract_address: (required) + :type contract_address: str + :param read_contract_request: (required) + :type read_contract_request: ReadContractRequest + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._read_contract_serialize( + network_id=network_id, + contract_address=contract_address, + read_contract_request=read_contract_request, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "SolidityValue", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + def read_contract_without_preload_content( + self, + network_id: StrictStr, + contract_address: StrictStr, + read_contract_request: ReadContractRequest, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """Read data from a smart contract + + Perform a read operation on a smart contract without creating a transaction + + :param network_id: (required) + :type network_id: str + :param contract_address: (required) + :type contract_address: str + :param read_contract_request: (required) + :type read_contract_request: ReadContractRequest + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._read_contract_serialize( + network_id=network_id, + contract_address=contract_address, + read_contract_request=read_contract_request, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "SolidityValue", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _read_contract_serialize( + self, + network_id, + contract_address, + read_contract_request, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = { + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[str, Union[str, bytes]] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + if network_id is not None: + _path_params['network_id'] = network_id + if contract_address is not None: + _path_params['contract_address'] = contract_address + # process the query parameters + # process the header parameters + # process the form parameters + # process the body parameter + if read_contract_request is not None: + _body_params = read_contract_request + + + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) + + # set the HTTP header `Content-Type` + if _content_type: + _header_params['Content-Type'] = _content_type + else: + _default_content_type = ( + self.api_client.select_header_content_type( + [ + 'application/json' + ] + ) + ) + if _default_content_type is not None: + _header_params['Content-Type'] = _default_content_type + + # authentication setting + _auth_settings: List[str] = [ + ] + + return self.api_client.param_serialize( + method='POST', + resource_path='/v1/networks/{network_id}/smart_contracts/{contract_address}/read', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + diff --git a/cdp/client/models/__init__.py b/cdp/client/models/__init__.py index 679d3cb..a342db7 100644 --- a/cdp/client/models/__init__.py +++ b/cdp/client/models/__init__.py @@ -64,6 +64,7 @@ from cdp.client.models.network_identifier import NetworkIdentifier from cdp.client.models.payload_signature import PayloadSignature from cdp.client.models.payload_signature_list import PayloadSignatureList +from cdp.client.models.read_contract_request import ReadContractRequest from cdp.client.models.seed_creation_event import SeedCreationEvent from cdp.client.models.seed_creation_event_result import SeedCreationEventResult from cdp.client.models.server_signer import ServerSigner @@ -78,6 +79,7 @@ from cdp.client.models.smart_contract_list import SmartContractList from cdp.client.models.smart_contract_options import SmartContractOptions from cdp.client.models.smart_contract_type import SmartContractType +from cdp.client.models.solidity_value import SolidityValue from cdp.client.models.sponsored_send import SponsoredSend from cdp.client.models.staking_balance import StakingBalance from cdp.client.models.staking_context import StakingContext diff --git a/cdp/client/models/read_contract_request.py b/cdp/client/models/read_contract_request.py new file mode 100644 index 0000000..0e90ce2 --- /dev/null +++ b/cdp/client/models/read_contract_request.py @@ -0,0 +1,91 @@ +# coding: utf-8 + +""" + Coinbase Platform API + + This is the OpenAPI 3.0 specification for the Coinbase Platform APIs, used in conjunction with the Coinbase Platform SDKs. + + The version of the OpenAPI document: 0.0.1-alpha + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, Field, StrictStr +from typing import Any, ClassVar, Dict, List, Optional +from typing import Optional, Set +from typing_extensions import Self + +class ReadContractRequest(BaseModel): + """ + ReadContractRequest + """ # noqa: E501 + method: StrictStr = Field(description="The name of the contract method to call") + args: StrictStr = Field(description="The JSON-encoded arguments to pass to the contract method. The keys should be the argument names and the values should be the argument values.") + abi: Optional[StrictStr] = Field(default=None, description="The JSON-encoded ABI of the contract method (optional, will use cached ABI if not provided)") + __properties: ClassVar[List[str]] = ["method", "args", "abi"] + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of ReadContractRequest from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of ReadContractRequest from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "method": obj.get("method"), + "args": obj.get("args"), + "abi": obj.get("abi") + }) + return _obj + + diff --git a/cdp/client/models/solidity_value.py b/cdp/client/models/solidity_value.py new file mode 100644 index 0000000..0efcf21 --- /dev/null +++ b/cdp/client/models/solidity_value.py @@ -0,0 +1,109 @@ +# coding: utf-8 + +""" + Coinbase Platform API + + This is the OpenAPI 3.0 specification for the Coinbase Platform APIs, used in conjunction with the Coinbase Platform SDKs. + + The version of the OpenAPI document: 0.0.1-alpha + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, Field, StrictStr, field_validator +from typing import Any, ClassVar, Dict, List, Optional +from typing import Optional, Set +from typing_extensions import Self + +class SolidityValue(BaseModel): + """ + SolidityValue + """ # noqa: E501 + type: StrictStr + name: Optional[StrictStr] = Field(default=None, description="The field name for tuple types. Not used for other types.") + value: Optional[StrictStr] = Field(default=None, description="The value as a string for simple types. Not used for complex types (array, tuple).") + values: Optional[List[SolidityValue]] = Field(default=None, description="For array and tuple types, the components of the value") + __properties: ClassVar[List[str]] = ["type", "name", "value", "values"] + + @field_validator('type') + def type_validate_enum(cls, value): + """Validates the enum""" + if value not in set(['uint8', 'uint16', 'uint32', 'uint64', 'uint128', 'uint256', 'int8', 'int16', 'int32', 'int64', 'int128', 'int256', 'address', 'bool', 'string', 'bytes', 'bytes1', 'bytes2', 'bytes3', 'bytes4', 'bytes5', 'bytes6', 'bytes7', 'bytes8', 'bytes9', 'bytes10', 'bytes11', 'bytes12', 'bytes13', 'bytes14', 'bytes15', 'bytes16', 'bytes17', 'bytes18', 'bytes19', 'bytes20', 'bytes21', 'bytes22', 'bytes23', 'bytes24', 'bytes25', 'bytes26', 'bytes27', 'bytes28', 'bytes29', 'bytes30', 'bytes31', 'bytes32', 'array', 'tuple']): + raise ValueError("must be one of enum values ('uint8', 'uint16', 'uint32', 'uint64', 'uint128', 'uint256', 'int8', 'int16', 'int32', 'int64', 'int128', 'int256', 'address', 'bool', 'string', 'bytes', 'bytes1', 'bytes2', 'bytes3', 'bytes4', 'bytes5', 'bytes6', 'bytes7', 'bytes8', 'bytes9', 'bytes10', 'bytes11', 'bytes12', 'bytes13', 'bytes14', 'bytes15', 'bytes16', 'bytes17', 'bytes18', 'bytes19', 'bytes20', 'bytes21', 'bytes22', 'bytes23', 'bytes24', 'bytes25', 'bytes26', 'bytes27', 'bytes28', 'bytes29', 'bytes30', 'bytes31', 'bytes32', 'array', 'tuple')") + return value + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of SolidityValue from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of each item in values (list) + _items = [] + if self.values: + for _item_values in self.values: + if _item_values: + _items.append(_item_values.to_dict()) + _dict['values'] = _items + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of SolidityValue from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "type": obj.get("type"), + "name": obj.get("name"), + "value": obj.get("value"), + "values": [SolidityValue.from_dict(_item) for _item in obj["values"]] if obj.get("values") is not None else None + }) + return _obj + +# TODO: Rewrite to not use raise_errors +SolidityValue.model_rebuild(raise_errors=False) + diff --git a/cdp/client/models/update_webhook_request.py b/cdp/client/models/update_webhook_request.py index 968bb1e..d7b6600 100644 --- a/cdp/client/models/update_webhook_request.py +++ b/cdp/client/models/update_webhook_request.py @@ -30,7 +30,7 @@ class UpdateWebhookRequest(BaseModel): """ # noqa: E501 event_type_filter: Optional[WebhookEventTypeFilter] = None event_filters: Optional[List[WebhookEventFilter]] = Field(default=None, description="Webhook will monitor all events that matches any one of the event filters.") - notification_uri: StrictStr = Field(description="The Webhook uri that updates to") + notification_uri: Optional[StrictStr] = Field(default=None, description="The Webhook uri that updates to") __properties: ClassVar[List[str]] = ["event_type_filter", "event_filters", "notification_uri"] model_config = ConfigDict( diff --git a/cdp/smart_contract.py b/cdp/smart_contract.py index 809793c..58b6e96 100644 --- a/cdp/smart_contract.py +++ b/cdp/smart_contract.py @@ -10,8 +10,10 @@ from cdp.client.models.deploy_smart_contract_request import DeploySmartContractRequest from cdp.client.models.multi_token_contract_options import MultiTokenContractOptions from cdp.client.models.nft_contract_options import NFTContractOptions +from cdp.client.models.read_contract_request import ReadContractRequest from cdp.client.models.smart_contract import SmartContract as SmartContractModel from cdp.client.models.smart_contract_options import SmartContractOptions +from cdp.client.models.solidity_value import SolidityValue from cdp.client.models.token_contract_options import TokenContractOptions from cdp.transaction import Transaction @@ -331,6 +333,88 @@ def create( return cls(model) + @classmethod + def read( + cls, + network_id: str, + contract_address: str, + method: str, + abi: list[dict] | None = None, + args: dict | None = None, + ) -> "SmartContract": + """Read data from a smart contract. + + Args: + network_id: The ID of the network. + contract_address: The address of the smart contract. + method: The method to call on the smart contract. + abi: The ABI of the smart contract. + args: The arguments to pass to the method. + + Returns: + The data read from the smart contract. + + """ + abi_json = None + + if abi: + abi_json = json.dumps(abi, separators=(",", ":")) + + read_contract_request = ReadContractRequest( + method=method, + abi=abi_json, + args=json.dumps(args or {}, separators=(",", ":")), + ) + + model = Cdp.api_clients.smart_contracts.read_contract( + network_id=network_id, + contract_address=contract_address, + read_contract_request=read_contract_request, + ) + return cls._convert_solidity_value(model) + + @classmethod + def _convert_solidity_value(cls, solidity_value: SolidityValue) -> Any: + type_ = solidity_value.type + value = getattr(solidity_value, "value", None) + values = getattr(solidity_value, "values", None) + + if type_ in [ + "uint8", + "uint16", + "uint32", + "uint64", + "uint128", + "uint256", + "int8", + "int16", + "int32", + "int64", + "int128", + "int256", + ]: + return int(value) if value is not None else None + elif type_ == "address": + return value + elif type_ == "bool": + return value == "true" if isinstance(value, str) else bool(value) + elif type_ == "string" or type_.startswith("bytes"): + return value + elif type_ == "array": + return [SmartContract._convert_solidity_value(v) for v in values] if values else [] + elif type_ == "tuple": + if values: + result = {} + for v in values: + if not hasattr(v, "name"): + raise ValueError("Error: Tuple value without a name") + result[v.name] = SmartContract._convert_solidity_value(v) + return result + else: + return {} + else: + raise ValueError(f"Unsupported Solidity type: {type_}") + def _update_transaction(self, model: SmartContractModel) -> None: """Update the transaction with the new model.""" if model.transaction is not None: diff --git a/tests/factories/smart_contract_factory.py b/tests/factories/smart_contract_factory.py index 4350848..99bc4da 100644 --- a/tests/factories/smart_contract_factory.py +++ b/tests/factories/smart_contract_factory.py @@ -38,3 +38,803 @@ def _create_smart_contract(status="complete"): return SmartContract(smart_contract_model) return _create_smart_contract + + +@pytest.fixture +def all_read_types_abi(): + """Return the ABI containing read functions for all types for testing.""" + return [ + { + "type": "function", + "name": "exampleFunction", + "inputs": [ + { + "name": "z", + "type": "uint256", + "internalType": "uint256", + }, + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool", + }, + ], + "stateMutability": "pure", + }, + { + "type": "function", + "name": "pureAddress", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "address", + }, + ], + "stateMutability": "pure", + }, + { + "type": "function", + "name": "pureArray", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256[]", + "internalType": "uint256[]", + }, + ], + "stateMutability": "pure", + }, + { + "type": "function", + "name": "pureBool", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool", + }, + ], + "stateMutability": "pure", + }, + { + "type": "function", + "name": "pureFunctionSelector", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes4", + "internalType": "bytes4", + }, + ], + "stateMutability": "pure", + }, + { + "type": "function", + "name": "pureInt128", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "int128", + "internalType": "int128", + }, + ], + "stateMutability": "pure", + }, + { + "type": "function", + "name": "pureInt16", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "int16", + "internalType": "int16", + }, + ], + "stateMutability": "pure", + }, + { + "type": "function", + "name": "pureInt256", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "int256", + "internalType": "int256", + }, + ], + "stateMutability": "pure", + }, + { + "type": "function", + "name": "pureInt32", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "int32", + "internalType": "int32", + }, + ], + "stateMutability": "pure", + }, + { + "type": "function", + "name": "pureInt64", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "int64", + "internalType": "int64", + }, + ], + "stateMutability": "pure", + }, + { + "type": "function", + "name": "pureInt8", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "int8", + "internalType": "int8", + }, + ], + "stateMutability": "pure", + }, + { + "type": "function", + "name": "pureNestedStruct", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "tuple", + "internalType": "struct TestAllReadTypes.ExampleStruct", + "components": [ + { + "name": "a", + "type": "uint256", + "internalType": "uint256", + }, + { + "name": "nestedFields", + "type": "tuple", + "internalType": "struct TestAllReadTypes.NestedData", + "components": [ + { + "name": "nestedArray", + "type": "tuple", + "internalType": "struct TestAllReadTypes.ArrayData", + "components": [ + { + "name": "a", + "type": "uint256[]", + "internalType": "uint256[]", + }, + ], + }, + { + "name": "a", + "type": "uint256", + "internalType": "uint256", + }, + ], + }, + ], + }, + ], + "stateMutability": "pure", + }, + { + "type": "function", + "name": "pureString", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "string", + "internalType": "string", + }, + ], + "stateMutability": "pure", + }, + { + "type": "function", + "name": "pureTuple", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256", + }, + { + "name": "", + "type": "uint256", + "internalType": "uint256", + }, + ], + "stateMutability": "pure", + }, + { + "type": "function", + "name": "pureTupleMixedTypes", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256", + }, + { + "name": "", + "type": "address", + "internalType": "address", + }, + { + "name": "", + "type": "bool", + "internalType": "bool", + }, + ], + "stateMutability": "pure", + }, + { + "type": "function", + "name": "pureUint128", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint128", + "internalType": "uint128", + }, + ], + "stateMutability": "pure", + }, + { + "type": "function", + "name": "pureUint16", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint16", + "internalType": "uint16", + }, + ], + "stateMutability": "pure", + }, + { + "type": "function", + "name": "pureUint256", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256", + }, + ], + "stateMutability": "pure", + }, + { + "type": "function", + "name": "pureUint32", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint32", + "internalType": "uint32", + }, + ], + "stateMutability": "pure", + }, + { + "type": "function", + "name": "pureUint64", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint64", + "internalType": "uint64", + }, + ], + "stateMutability": "pure", + }, + { + "type": "function", + "name": "pureUint8", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint8", + "internalType": "uint8", + }, + ], + "stateMutability": "pure", + }, + { + "type": "function", + "name": "returnFunction", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "function", + "internalType": "function (uint256) external returns (bool)", + }, + ], + "stateMutability": "view", + }, + { + "type": "function", + "name": "viewUint", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256", + }, + ], + "stateMutability": "view", + }, + { + "type": "function", + "name": "x", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256", + }, + ], + "stateMutability": "view", + }, + { + "type": "function", + "name": "pureBytes", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes", + "internalType": "bytes", + }, + ], + "stateMutability": "pure", + }, + { + "type": "function", + "name": "pureBytes1", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes1", + "internalType": "bytes1", + }, + ], + "stateMutability": "pure", + }, + { + "type": "function", + "name": "pureBytes2", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes2", + "internalType": "bytes2", + }, + ], + "stateMutability": "pure", + }, + { + "type": "function", + "name": "pureBytes3", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes3", + "internalType": "bytes3", + }, + ], + "stateMutability": "pure", + }, + { + "type": "function", + "name": "pureBytes4", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes4", + "internalType": "bytes4", + }, + ], + "stateMutability": "pure", + }, + { + "type": "function", + "name": "pureBytes5", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes5", + "internalType": "bytes5", + }, + ], + "stateMutability": "pure", + }, + { + "type": "function", + "name": "pureBytes6", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes6", + "internalType": "bytes6", + }, + ], + "stateMutability": "pure", + }, + { + "type": "function", + "name": "pureBytes7", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes7", + "internalType": "bytes7", + }, + ], + "stateMutability": "pure", + }, + { + "type": "function", + "name": "pureBytes8", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes8", + "internalType": "bytes8", + }, + ], + "stateMutability": "pure", + }, + { + "type": "function", + "name": "pureBytes9", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes9", + "internalType": "bytes9", + }, + ], + "stateMutability": "pure", + }, + { + "type": "function", + "name": "pureBytes10", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes10", + "internalType": "bytes10", + }, + ], + "stateMutability": "pure", + }, + { + "type": "function", + "name": "pureBytes11", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes11", + "internalType": "bytes11", + }, + ], + "stateMutability": "pure", + }, + { + "type": "function", + "name": "pureBytes12", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes12", + "internalType": "bytes12", + }, + ], + "stateMutability": "pure", + }, + { + "type": "function", + "name": "pureBytes13", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes13", + "internalType": "bytes13", + }, + ], + "stateMutability": "pure", + }, + { + "type": "function", + "name": "pureBytes14", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes14", + "internalType": "bytes14", + }, + ], + "stateMutability": "pure", + }, + { + "type": "function", + "name": "pureBytes15", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes15", + "internalType": "bytes15", + }, + ], + "stateMutability": "pure", + }, + { + "type": "function", + "name": "pureBytes16", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes16", + "internalType": "bytes16", + }, + ], + "stateMutability": "pure", + }, + { + "type": "function", + "name": "pureBytes17", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes17", + "internalType": "bytes17", + }, + ], + "stateMutability": "pure", + }, + { + "type": "function", + "name": "pureBytes18", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes18", + "internalType": "bytes18", + }, + ], + "stateMutability": "pure", + }, + { + "type": "function", + "name": "pureBytes19", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes19", + "internalType": "bytes19", + }, + ], + "stateMutability": "pure", + }, + { + "type": "function", + "name": "pureBytes20", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes20", + "internalType": "bytes20", + }, + ], + "stateMutability": "pure", + }, + { + "type": "function", + "name": "pureBytes21", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes21", + "internalType": "bytes21", + }, + ], + "stateMutability": "pure", + }, + { + "type": "function", + "name": "pureBytes22", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes22", + "internalType": "bytes22", + }, + ], + "stateMutability": "pure", + }, + { + "type": "function", + "name": "pureBytes23", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes23", + "internalType": "bytes23", + }, + ], + "stateMutability": "pure", + }, + { + "type": "function", + "name": "pureBytes24", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes24", + "internalType": "bytes24", + }, + ], + "stateMutability": "pure", + }, + { + "type": "function", + "name": "pureBytes25", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes25", + "internalType": "bytes25", + }, + ], + "stateMutability": "pure", + }, + { + "type": "function", + "name": "pureBytes26", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes26", + "internalType": "bytes26", + }, + ], + "stateMutability": "pure", + }, + { + "type": "function", + "name": "pureBytes27", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes27", + "internalType": "bytes27", + }, + ], + "stateMutability": "pure", + }, + { + "type": "function", + "name": "pureBytes28", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes28", + "internalType": "bytes28", + }, + ], + "stateMutability": "pure", + }, + { + "type": "function", + "name": "pureBytes29", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes29", + "internalType": "bytes29", + }, + ], + "stateMutability": "pure", + }, + { + "type": "function", + "name": "pureBytes30", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes30", + "internalType": "bytes30", + }, + ], + "stateMutability": "pure", + }, + { + "type": "function", + "name": "pureBytes31", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes31", + "internalType": "bytes31", + }, + ], + "stateMutability": "pure", + }, + { + "type": "function", + "name": "pureBytes32", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32", + }, + ], + "stateMutability": "pure", + }, + ] diff --git a/tests/test_smart_contract.py b/tests/test_smart_contract.py index 2c2876d..591aa42 100644 --- a/tests/test_smart_contract.py +++ b/tests/test_smart_contract.py @@ -2,6 +2,7 @@ import pytest +from cdp.client.models.solidity_value import SolidityValue from cdp.smart_contract import SmartContract @@ -174,3 +175,1385 @@ def test_smart_contract_repr(smart_contract_factory): """Test the representation of a SmartContract object.""" smart_contract = smart_contract_factory() assert repr(smart_contract) == str(smart_contract) + + +@patch("cdp.Cdp.api_clients") +def test_read_pure_string(mock_api_clients, all_read_types_abi): + """Test reading a string value from a pure function.""" + mock_read_contract = Mock() + mock_read_contract.return_value = SolidityValue(type="string", value="Hello, World!") + mock_api_clients.smart_contracts.read_contract = mock_read_contract + + result = SmartContract.read( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + method="pureString", + abi=all_read_types_abi, + ) + + assert result == "Hello, World!" + mock_read_contract.assert_called_once_with( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + read_contract_request=ANY, + ) + + +@patch("cdp.Cdp.api_clients") +def test_read_pure_bytes1(mock_api_clients, all_read_types_abi): + """Test reading a bytes1 value from a pure function.""" + mock_read_contract = Mock() + mock_read_contract.return_value = SolidityValue(type="bytes1", value="0x01") + mock_api_clients.smart_contracts.read_contract = mock_read_contract + + result = SmartContract.read( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + method="pureBytes1", + abi=all_read_types_abi, + ) + + assert result == "0x01" + mock_read_contract.assert_called_once_with( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + read_contract_request=ANY, + ) + + +@patch("cdp.Cdp.api_clients") +def test_read_pure_bytes2(mock_api_clients, all_read_types_abi): + """Test reading a bytes2 value from a pure function.""" + mock_read_contract = Mock() + mock_read_contract.return_value = SolidityValue(type="bytes2", value="0x0102") + mock_api_clients.smart_contracts.read_contract = mock_read_contract + + result = SmartContract.read( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + method="pureBytes2", + abi=all_read_types_abi, + ) + + assert result == "0x0102" + mock_read_contract.assert_called_once_with( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + read_contract_request=ANY, + ) + + +@patch("cdp.Cdp.api_clients") +def test_read_pure_bytes3(mock_api_clients, all_read_types_abi): + """Test reading a bytes3 value from a pure function.""" + mock_read_contract = Mock() + mock_read_contract.return_value = SolidityValue(type="bytes3", value="0x010203") + mock_api_clients.smart_contracts.read_contract = mock_read_contract + + result = SmartContract.read( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + method="pureBytes3", + abi=all_read_types_abi, + ) + + assert result == "0x010203" + mock_read_contract.assert_called_once_with( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + read_contract_request=ANY, + ) + + +@patch("cdp.Cdp.api_clients") +def test_read_pure_bytes4(mock_api_clients, all_read_types_abi): + """Test reading a bytes4 value from a pure function.""" + mock_read_contract = Mock() + mock_read_contract.return_value = SolidityValue(type="bytes4", value="0x01020304") + mock_api_clients.smart_contracts.read_contract = mock_read_contract + + result = SmartContract.read( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + method="pureBytes4", + abi=all_read_types_abi, + ) + + assert result == "0x01020304" + mock_read_contract.assert_called_once_with( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + read_contract_request=ANY, + ) + + +@patch("cdp.Cdp.api_clients") +def test_read_pure_bytes5(mock_api_clients, all_read_types_abi): + """Test reading a bytes5 value from a pure function.""" + mock_read_contract = Mock() + mock_read_contract.return_value = SolidityValue(type="bytes5", value="0x0102030405") + mock_api_clients.smart_contracts.read_contract = mock_read_contract + + result = SmartContract.read( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + method="pureBytes5", + abi=all_read_types_abi, + ) + + assert result == "0x0102030405" + mock_read_contract.assert_called_once_with( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + read_contract_request=ANY, + ) + + +@patch("cdp.Cdp.api_clients") +def test_read_pure_bytes6(mock_api_clients, all_read_types_abi): + """Test reading a bytes6 value from a pure function.""" + mock_read_contract = Mock() + mock_read_contract.return_value = SolidityValue(type="bytes6", value="0x010203040506") + mock_api_clients.smart_contracts.read_contract = mock_read_contract + + result = SmartContract.read( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + method="pureBytes6", + abi=all_read_types_abi, + ) + + assert result == "0x010203040506" + mock_read_contract.assert_called_once_with( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + read_contract_request=ANY, + ) + + +@patch("cdp.Cdp.api_clients") +def test_read_pure_bytes7(mock_api_clients, all_read_types_abi): + """Test reading a bytes7 value from a pure function.""" + mock_read_contract = Mock() + mock_read_contract.return_value = SolidityValue(type="bytes7", value="0x01020304050607") + mock_api_clients.smart_contracts.read_contract = mock_read_contract + + result = SmartContract.read( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + method="pureBytes7", + abi=all_read_types_abi, + ) + + assert result == "0x01020304050607" + mock_read_contract.assert_called_once_with( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + read_contract_request=ANY, + ) + + +@patch("cdp.Cdp.api_clients") +def test_read_pure_bytes8(mock_api_clients, all_read_types_abi): + """Test reading a bytes8 value from a pure function.""" + mock_read_contract = Mock() + mock_read_contract.return_value = SolidityValue(type="bytes8", value="0x0102030405060708") + mock_api_clients.smart_contracts.read_contract = mock_read_contract + + result = SmartContract.read( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + method="pureBytes8", + abi=all_read_types_abi, + ) + + assert result == "0x0102030405060708" + mock_read_contract.assert_called_once_with( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + read_contract_request=ANY, + ) + + +@patch("cdp.Cdp.api_clients") +def test_read_pure_bytes9(mock_api_clients, all_read_types_abi): + """Test reading a bytes9 value from a pure function.""" + mock_read_contract = Mock() + mock_read_contract.return_value = SolidityValue(type="bytes9", value="0x010203040506070809") + mock_api_clients.smart_contracts.read_contract = mock_read_contract + + result = SmartContract.read( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + method="pureBytes9", + abi=all_read_types_abi, + ) + + assert result == "0x010203040506070809" + mock_read_contract.assert_called_once_with( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + read_contract_request=ANY, + ) + + +@patch("cdp.Cdp.api_clients") +def test_read_pure_bytes10(mock_api_clients, all_read_types_abi): + """Test reading a bytes10 value from a pure function.""" + mock_read_contract = Mock() + mock_read_contract.return_value = SolidityValue(type="bytes10", value="0x01020304050607080910") + mock_api_clients.smart_contracts.read_contract = mock_read_contract + + result = SmartContract.read( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + method="pureBytes10", + abi=all_read_types_abi, + ) + + assert result == "0x01020304050607080910" + mock_read_contract.assert_called_once_with( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + read_contract_request=ANY, + ) + + +@patch("cdp.Cdp.api_clients") +def test_read_pure_bytes11(mock_api_clients, all_read_types_abi): + """Test reading a bytes11 value from a pure function.""" + mock_read_contract = Mock() + mock_read_contract.return_value = SolidityValue( + type="bytes11", value="0x0102030405060708091011" + ) + mock_api_clients.smart_contracts.read_contract = mock_read_contract + + result = SmartContract.read( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + method="pureBytes11", + abi=all_read_types_abi, + ) + + assert result == "0x0102030405060708091011" + mock_read_contract.assert_called_once_with( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + read_contract_request=ANY, + ) + + +@patch("cdp.Cdp.api_clients") +def test_read_pure_bytes12(mock_api_clients, all_read_types_abi): + """Test reading a bytes12 value from a pure function.""" + mock_read_contract = Mock() + mock_read_contract.return_value = SolidityValue( + type="bytes12", value="0x010203040506070809101112" + ) + mock_api_clients.smart_contracts.read_contract = mock_read_contract + + result = SmartContract.read( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + method="pureBytes12", + abi=all_read_types_abi, + ) + + assert result == "0x010203040506070809101112" + mock_read_contract.assert_called_once_with( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + read_contract_request=ANY, + ) + + +@patch("cdp.Cdp.api_clients") +def test_read_pure_bytes13(mock_api_clients, all_read_types_abi): + """Test reading a bytes13 value from a pure function.""" + mock_read_contract = Mock() + mock_read_contract.return_value = SolidityValue( + type="bytes13", value="0x01020304050607080910111213" + ) + mock_api_clients.smart_contracts.read_contract = mock_read_contract + + result = SmartContract.read( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + method="pureBytes13", + abi=all_read_types_abi, + ) + + assert result == "0x01020304050607080910111213" + mock_read_contract.assert_called_once_with( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + read_contract_request=ANY, + ) + + +@patch("cdp.Cdp.api_clients") +def test_read_pure_bytes14(mock_api_clients, all_read_types_abi): + """Test reading a bytes14 value from a pure function.""" + mock_read_contract = Mock() + mock_read_contract.return_value = SolidityValue( + type="bytes14", value="0x0102030405060708091011121314" + ) + mock_api_clients.smart_contracts.read_contract = mock_read_contract + + result = SmartContract.read( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + method="pureBytes14", + abi=all_read_types_abi, + ) + + assert result == "0x0102030405060708091011121314" + mock_read_contract.assert_called_once_with( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + read_contract_request=ANY, + ) + + +@patch("cdp.Cdp.api_clients") +def test_read_pure_bytes15(mock_api_clients, all_read_types_abi): + """Test reading a bytes15 value from a pure function.""" + mock_read_contract = Mock() + mock_read_contract.return_value = SolidityValue( + type="bytes15", value="0x010203040506070809101112131415" + ) + mock_api_clients.smart_contracts.read_contract = mock_read_contract + + result = SmartContract.read( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + method="pureBytes15", + abi=all_read_types_abi, + ) + + assert result == "0x010203040506070809101112131415" + mock_read_contract.assert_called_once_with( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + read_contract_request=ANY, + ) + + +@patch("cdp.Cdp.api_clients") +def test_read_pure_bytes16(mock_api_clients, all_read_types_abi): + """Test reading a bytes16 value from a pure function.""" + mock_read_contract = Mock() + mock_read_contract.return_value = SolidityValue( + type="bytes16", value="0x0102030405060708090a0b0c0d0e0f10" + ) + mock_api_clients.smart_contracts.read_contract = mock_read_contract + + result = SmartContract.read( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + method="pureBytes16", + abi=all_read_types_abi, + ) + + assert result == "0x0102030405060708090a0b0c0d0e0f10" + mock_read_contract.assert_called_once_with( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + read_contract_request=ANY, + ) + + +@patch("cdp.Cdp.api_clients") +def test_read_pure_bytes17(mock_api_clients, all_read_types_abi): + """Test reading a bytes17 value from a pure function.""" + mock_read_contract = Mock() + mock_read_contract.return_value = SolidityValue( + type="bytes17", value="0x0102030405060708090a0b0c0d0e0f1011" + ) + mock_api_clients.smart_contracts.read_contract = mock_read_contract + + result = SmartContract.read( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + method="pureBytes17", + abi=all_read_types_abi, + ) + + assert result == "0x0102030405060708090a0b0c0d0e0f1011" + mock_read_contract.assert_called_once_with( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + read_contract_request=ANY, + ) + + +@patch("cdp.Cdp.api_clients") +def test_read_pure_bytes18(mock_api_clients, all_read_types_abi): + """Test reading a bytes18 value from a pure function.""" + mock_read_contract = Mock() + mock_read_contract.return_value = SolidityValue( + type="bytes18", value="0x0102030405060708090a0b0c0d0e0f101112" + ) + mock_api_clients.smart_contracts.read_contract = mock_read_contract + + result = SmartContract.read( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + method="pureBytes18", + abi=all_read_types_abi, + ) + + assert result == "0x0102030405060708090a0b0c0d0e0f101112" + mock_read_contract.assert_called_once_with( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + read_contract_request=ANY, + ) + + +@patch("cdp.Cdp.api_clients") +def test_read_pure_bytes19(mock_api_clients, all_read_types_abi): + """Test reading a bytes19 value from a pure function.""" + mock_read_contract = Mock() + mock_read_contract.return_value = SolidityValue( + type="bytes19", value="0x0102030405060708090a0b0c0d0e0f10111213" + ) + mock_api_clients.smart_contracts.read_contract = mock_read_contract + + result = SmartContract.read( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + method="pureBytes19", + abi=all_read_types_abi, + ) + + assert result == "0x0102030405060708090a0b0c0d0e0f10111213" + mock_read_contract.assert_called_once_with( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + read_contract_request=ANY, + ) + + +@patch("cdp.Cdp.api_clients") +def test_read_pure_bytes20(mock_api_clients, all_read_types_abi): + """Test reading a bytes20 value from a pure function.""" + mock_read_contract = Mock() + mock_read_contract.return_value = SolidityValue( + type="bytes20", value="0x0102030405060708090a0b0c0d0e0f1011121314" + ) + mock_api_clients.smart_contracts.read_contract = mock_read_contract + + result = SmartContract.read( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + method="pureBytes20", + abi=all_read_types_abi, + ) + + assert result == "0x0102030405060708090a0b0c0d0e0f1011121314" + mock_read_contract.assert_called_once_with( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + read_contract_request=ANY, + ) + + +@patch("cdp.Cdp.api_clients") +def test_read_pure_bytes21(mock_api_clients, all_read_types_abi): + """Test reading a bytes21 value from a pure function.""" + mock_read_contract = Mock() + mock_read_contract.return_value = SolidityValue( + type="bytes21", value="0x0102030405060708090a0b0c0d0e0f10111213141516" + ) + mock_api_clients.smart_contracts.read_contract = mock_read_contract + + result = SmartContract.read( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + method="pureBytes21", + abi=all_read_types_abi, + ) + + assert result == "0x0102030405060708090a0b0c0d0e0f10111213141516" + mock_read_contract.assert_called_once_with( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + read_contract_request=ANY, + ) + + +@patch("cdp.Cdp.api_clients") +def test_read_pure_bytes22(mock_api_clients, all_read_types_abi): + """Test reading a bytes22 value from a pure function.""" + mock_read_contract = Mock() + mock_read_contract.return_value = SolidityValue( + type="bytes22", value="0x0102030405060708090a0b0c0d0e0f10111213141516171819" + ) + mock_api_clients.smart_contracts.read_contract = mock_read_contract + + result = SmartContract.read( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + method="pureBytes22", + abi=all_read_types_abi, + ) + + assert result == "0x0102030405060708090a0b0c0d0e0f10111213141516171819" + mock_read_contract.assert_called_once_with( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + read_contract_request=ANY, + ) + + +@patch("cdp.Cdp.api_clients") +def test_read_pure_bytes23(mock_api_clients, all_read_types_abi): + """Test reading a bytes23 value from a pure function.""" + mock_read_contract = Mock() + mock_read_contract.return_value = SolidityValue( + type="bytes23", value="0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f2021" + ) + mock_api_clients.smart_contracts.read_contract = mock_read_contract + + result = SmartContract.read( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + method="pureBytes23", + abi=all_read_types_abi, + ) + + assert result == "0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f2021" + mock_read_contract.assert_called_once_with( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + read_contract_request=ANY, + ) + + +@patch("cdp.Cdp.api_clients") +def test_read_pure_bytes24(mock_api_clients, all_read_types_abi): + """Test reading a bytes24 value from a pure function.""" + mock_read_contract = Mock() + mock_read_contract.return_value = SolidityValue( + type="bytes24", + value="0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122", + ) + mock_api_clients.smart_contracts.read_contract = mock_read_contract + + result = SmartContract.read( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + method="pureBytes24", + abi=all_read_types_abi, + ) + + assert result == "0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122" + mock_read_contract.assert_called_once_with( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + read_contract_request=ANY, + ) + + +@patch("cdp.Cdp.api_clients") +def test_read_pure_bytes25(mock_api_clients, all_read_types_abi): + """Test reading a bytes25 value from a pure function.""" + mock_read_contract = Mock() + mock_read_contract.return_value = SolidityValue( + type="bytes25", + value="0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20212223", + ) + mock_api_clients.smart_contracts.read_contract = mock_read_contract + + result = SmartContract.read( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + method="pureBytes25", + abi=all_read_types_abi, + ) + + assert result == "0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20212223" + mock_read_contract.assert_called_once_with( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + read_contract_request=ANY, + ) + + +@patch("cdp.Cdp.api_clients") +def test_read_pure_bytes26(mock_api_clients, all_read_types_abi): + """Test reading a bytes26 value from a pure function.""" + mock_read_contract = Mock() + mock_read_contract.return_value = SolidityValue( + type="bytes26", + value="0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425", + ) + mock_api_clients.smart_contracts.read_contract = mock_read_contract + + result = SmartContract.read( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + method="pureBytes26", + abi=all_read_types_abi, + ) + + assert result == "0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425" + mock_read_contract.assert_called_once_with( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + read_contract_request=ANY, + ) + + +@patch("cdp.Cdp.api_clients") +def test_read_pure_bytes27(mock_api_clients, all_read_types_abi): + """Test reading a bytes27 value from a pure function.""" + mock_read_contract = Mock() + mock_read_contract.return_value = SolidityValue( + type="bytes27", + value="0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f2021222324252627", + ) + mock_api_clients.smart_contracts.read_contract = mock_read_contract + + result = SmartContract.read( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + method="pureBytes27", + abi=all_read_types_abi, + ) + + assert ( + result == "0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f2021222324252627" + ) + mock_read_contract.assert_called_once_with( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + read_contract_request=ANY, + ) + + +@patch("cdp.Cdp.api_clients") +def test_read_pure_bytes28(mock_api_clients, all_read_types_abi): + """Test reading a bytes28 value from a pure function.""" + mock_read_contract = Mock() + mock_read_contract.return_value = SolidityValue( + type="bytes28", value="0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c" + ) + mock_api_clients.smart_contracts.read_contract = mock_read_contract + + result = SmartContract.read( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + method="pureBytes28", + abi=all_read_types_abi, + ) + + assert result == "0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c" + mock_read_contract.assert_called_once_with( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + read_contract_request=ANY, + ) + + +@patch("cdp.Cdp.api_clients") +def test_read_pure_bytes29(mock_api_clients, all_read_types_abi): + """Test reading a bytes29 value from a pure function.""" + mock_read_contract = Mock() + mock_read_contract.return_value = SolidityValue( + type="bytes29", value="0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d" + ) + mock_api_clients.smart_contracts.read_contract = mock_read_contract + + result = SmartContract.read( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + method="pureBytes29", + abi=all_read_types_abi, + ) + + assert result == "0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d" + mock_read_contract.assert_called_once_with( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + read_contract_request=ANY, + ) + + +@patch("cdp.Cdp.api_clients") +def test_read_pure_bytes30(mock_api_clients, all_read_types_abi): + """Test reading a bytes30 value from a pure function.""" + mock_read_contract = Mock() + mock_read_contract.return_value = SolidityValue( + type="bytes30", value="0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e" + ) + mock_api_clients.smart_contracts.read_contract = mock_read_contract + + result = SmartContract.read( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + method="pureBytes30", + abi=all_read_types_abi, + ) + + assert result == "0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e" + mock_read_contract.assert_called_once_with( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + read_contract_request=ANY, + ) + + +@patch("cdp.Cdp.api_clients") +def test_read_pure_bytes31(mock_api_clients, all_read_types_abi): + """Test reading a bytes31 value from a pure function.""" + mock_read_contract = Mock() + mock_read_contract.return_value = SolidityValue( + type="bytes31", value="0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" + ) + mock_api_clients.smart_contracts.read_contract = mock_read_contract + + result = SmartContract.read( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + method="pureBytes31", + abi=all_read_types_abi, + ) + + assert result == "0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" + mock_read_contract.assert_called_once_with( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + read_contract_request=ANY, + ) + + +@patch("cdp.Cdp.api_clients") +def test_read_pure_bytes32(mock_api_clients, all_read_types_abi): + """Test reading a bytes32 value from a pure function.""" + mock_read_contract = Mock() + mock_read_contract.return_value = SolidityValue( + type="bytes32", value="0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20" + ) + mock_api_clients.smart_contracts.read_contract = mock_read_contract + + result = SmartContract.read( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + method="pureBytes32", + abi=all_read_types_abi, + ) + + assert result == "0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20" + mock_read_contract.assert_called_once_with( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + read_contract_request=ANY, + ) + + +@patch("cdp.Cdp.api_clients") +def test_read_pure_bytes(mock_api_clients, all_read_types_abi): + """Test reading a bytes value from a pure function.""" + mock_read_contract = Mock() + mock_read_contract.return_value = SolidityValue( + type="bytes", + value="0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20212223242526272829", + ) + mock_api_clients.smart_contracts.read_contract = mock_read_contract + + result = SmartContract.read( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + method="pureBytes", + abi=all_read_types_abi, + ) + + assert ( + result + == "0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20212223242526272829" + ) + mock_read_contract.assert_called_once_with( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + read_contract_request=ANY, + ) + + +@patch("cdp.Cdp.api_clients") +def test_read_pure_uint8(mock_api_clients, all_read_types_abi): + """Test reading a uint8 value from a pure function.""" + mock_read_contract = Mock() + mock_read_contract.return_value = SolidityValue(type="uint8", value="123") + mock_api_clients.smart_contracts.read_contract = mock_read_contract + + result = SmartContract.read( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + method="pureUint8", + abi=all_read_types_abi, + ) + + assert result == 123 + mock_read_contract.assert_called_once_with( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + read_contract_request=ANY, + ) + + +@patch("cdp.Cdp.api_clients") +def test_read_pure_uint16(mock_api_clients, all_read_types_abi): + """Test reading a uint16 value from a pure function.""" + mock_read_contract = Mock() + mock_read_contract.return_value = SolidityValue(type="uint16", value="12345") + mock_api_clients.smart_contracts.read_contract = mock_read_contract + + result = SmartContract.read( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + method="pureUint16", + abi=all_read_types_abi, + ) + + assert result == 12345 + mock_read_contract.assert_called_once_with( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + read_contract_request=ANY, + ) + + +@patch("cdp.Cdp.api_clients") +def test_read_pure_uint32(mock_api_clients, all_read_types_abi): + """Test reading a uint32 value from a pure function.""" + mock_read_contract = Mock() + mock_read_contract.return_value = SolidityValue(type="uint32", value="4294967295") + mock_api_clients.smart_contracts.read_contract = mock_read_contract + + result = SmartContract.read( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + method="pureUint32", + abi=all_read_types_abi, + ) + + assert result == 4294967295 + mock_read_contract.assert_called_once_with( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + read_contract_request=ANY, + ) + + +@patch("cdp.Cdp.api_clients") +def test_read_pure_uint64(mock_api_clients, all_read_types_abi): + """Test reading a uint64 value from a pure function.""" + mock_read_contract = Mock() + mock_read_contract.return_value = SolidityValue(type="uint64", value="18446744073709551615") + mock_api_clients.smart_contracts.read_contract = mock_read_contract + + result = SmartContract.read( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + method="pureUint64", + abi=all_read_types_abi, + ) + + assert result == 18446744073709551615 + mock_read_contract.assert_called_once_with( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + read_contract_request=ANY, + ) + + +@patch("cdp.Cdp.api_clients") +def test_read_pure_uint128(mock_api_clients, all_read_types_abi): + """Test reading a uint128 value from a pure function.""" + mock_read_contract = Mock() + mock_read_contract.return_value = SolidityValue( + type="uint128", value="340282366920938463463374607431768211455" + ) + mock_api_clients.smart_contracts.read_contract = mock_read_contract + + result = SmartContract.read( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + method="pureUint128", + abi=all_read_types_abi, + ) + + assert result == 340282366920938463463374607431768211455 + mock_read_contract.assert_called_once_with( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + read_contract_request=ANY, + ) + + +@patch("cdp.Cdp.api_clients") +def test_read_pure_uint256(mock_api_clients, all_read_types_abi): + """Test reading a uint256 value from a pure function.""" + mock_read_contract = Mock() + mock_read_contract.return_value = SolidityValue( + type="uint256", + value="115792089237316195423570985008687907853269984665640564039457584007913129639935", + ) + mock_api_clients.smart_contracts.read_contract = mock_read_contract + + result = SmartContract.read( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + method="pureUint256", + abi=all_read_types_abi, + ) + + assert result == 115792089237316195423570985008687907853269984665640564039457584007913129639935 + mock_read_contract.assert_called_once_with( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + read_contract_request=ANY, + ) + + +@patch("cdp.Cdp.api_clients") +def test_read_pure_int8(mock_api_clients, all_read_types_abi): + """Test reading an int8 value from a pure function.""" + mock_read_contract = Mock() + mock_read_contract.return_value = SolidityValue(type="int8", value="-128") + mock_api_clients.smart_contracts.read_contract = mock_read_contract + + result = SmartContract.read( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + method="pureInt8", + abi=all_read_types_abi, + ) + + assert result == -128 + mock_read_contract.assert_called_once_with( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + read_contract_request=ANY, + ) + + +@patch("cdp.Cdp.api_clients") +def test_read_pure_int16(mock_api_clients, all_read_types_abi): + """Test reading an int16 value from a pure function.""" + mock_read_contract = Mock() + mock_read_contract.return_value = SolidityValue(type="int16", value="-32768") + mock_api_clients.smart_contracts.read_contract = mock_read_contract + + result = SmartContract.read( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + method="pureInt16", + abi=all_read_types_abi, + ) + + assert result == -32768 + mock_read_contract.assert_called_once_with( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + read_contract_request=ANY, + ) + + +@patch("cdp.Cdp.api_clients") +def test_read_pure_int32(mock_api_clients, all_read_types_abi): + """Test reading an int32 value from a pure function.""" + mock_read_contract = Mock() + mock_read_contract.return_value = SolidityValue(type="int32", value="-2147483648") + mock_api_clients.smart_contracts.read_contract = mock_read_contract + + result = SmartContract.read( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + method="pureInt32", + abi=all_read_types_abi, + ) + + assert result == -2147483648 + mock_read_contract.assert_called_once_with( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + read_contract_request=ANY, + ) + + +@patch("cdp.Cdp.api_clients") +def test_read_pure_int64(mock_api_clients, all_read_types_abi): + """Test reading an int64 value from a pure function.""" + mock_read_contract = Mock() + mock_read_contract.return_value = SolidityValue(type="int64", value="-9223372036854775808") + mock_api_clients.smart_contracts.read_contract = mock_read_contract + + result = SmartContract.read( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + method="pureInt64", + abi=all_read_types_abi, + ) + + assert result == -9223372036854775808 + mock_read_contract.assert_called_once_with( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + read_contract_request=ANY, + ) + + +@patch("cdp.Cdp.api_clients") +def test_read_pure_int128(mock_api_clients, all_read_types_abi): + """Test reading an int128 value from a pure function.""" + mock_read_contract = Mock() + mock_read_contract.return_value = SolidityValue( + type="int128", value="-170141183460469231731687303715884105728" + ) + mock_api_clients.smart_contracts.read_contract = mock_read_contract + + result = SmartContract.read( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + method="pureInt128", + abi=all_read_types_abi, + ) + + assert result == -170141183460469231731687303715884105728 + mock_read_contract.assert_called_once_with( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + read_contract_request=ANY, + ) + + +@patch("cdp.Cdp.api_clients") +def test_read_pure_int256(mock_api_clients, all_read_types_abi): + """Test reading an int256 value from a pure function.""" + mock_read_contract = Mock() + mock_read_contract.return_value = SolidityValue( + type="int256", + value="-57896044618658097711785492504343953926634992332820282019728792003956564819968", + ) + mock_api_clients.smart_contracts.read_contract = mock_read_contract + + result = SmartContract.read( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + method="pureInt256", + abi=all_read_types_abi, + ) + + assert result == -57896044618658097711785492504343953926634992332820282019728792003956564819968 + mock_read_contract.assert_called_once_with( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + read_contract_request=ANY, + ) + + +@patch("cdp.Cdp.api_clients") +def test_read_pure_address(mock_api_clients, all_read_types_abi): + """Test reading an address value from a pure function.""" + mock_read_contract = Mock() + mock_read_contract.return_value = SolidityValue( + type="address", value="0x742d35Cc6634C0532925a3b844Bc454e4438f44e" + ) + mock_api_clients.smart_contracts.read_contract = mock_read_contract + + result = SmartContract.read( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + method="pureAddress", + abi=all_read_types_abi, + ) + + assert result == "0x742d35Cc6634C0532925a3b844Bc454e4438f44e" + mock_read_contract.assert_called_once_with( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + read_contract_request=ANY, + ) + + +@patch("cdp.Cdp.api_clients") +def test_read_pure_bool(mock_api_clients, all_read_types_abi): + """Test reading a boolean value from a pure function.""" + mock_read_contract = Mock() + mock_read_contract.return_value = SolidityValue(type="bool", value="true") + mock_api_clients.smart_contracts.read_contract = mock_read_contract + + result = SmartContract.read( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + method="pureBool", + abi=all_read_types_abi, + ) + + assert result is True + mock_read_contract.assert_called_once_with( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + read_contract_request=ANY, + ) + + +@patch("cdp.Cdp.api_clients") +def test_read_pure_array(mock_api_clients, all_read_types_abi): + """Test reading an array value from a pure function.""" + mock_read_contract = Mock() + mock_read_contract.return_value = SolidityValue( + type="array", + values=[ + SolidityValue(type="uint256", value="1"), + SolidityValue(type="uint256", value="2"), + SolidityValue(type="uint256", value="3"), + SolidityValue(type="uint256", value="4"), + SolidityValue(type="uint256", value="5"), + ], + ) + mock_api_clients.smart_contracts.read_contract = mock_read_contract + + result = SmartContract.read( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + method="pureArray", + abi=all_read_types_abi, + ) + + assert result == [1, 2, 3, 4, 5] # Note: In Python, we use regular integers, not BigInt + mock_read_contract.assert_called_once_with( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + read_contract_request=ANY, + ) + + +@patch("cdp.Cdp.api_clients") +def test_read_return_function(mock_api_clients, all_read_types_abi): + """Test reading a function type as bytes from a view function.""" + mock_read_contract = Mock() + mock_read_contract.return_value = SolidityValue( + type="bytes", value="0x12341234123412341234123400000000" + ) + mock_api_clients.smart_contracts.read_contract = mock_read_contract + + result = SmartContract.read( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + method="returnFunction", + abi=all_read_types_abi, + ) + + assert result == "0x12341234123412341234123400000000" + mock_read_contract.assert_called_once_with( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + read_contract_request=ANY, + ) + + +@patch("cdp.Cdp.api_clients") +def test_read_pure_tuple(mock_api_clients, all_read_types_abi): + """Test reading a tuple value from a pure function.""" + mock_read_contract = Mock() + mock_read_contract.return_value = SolidityValue( + type="tuple", + values=[ + SolidityValue(type="uint256", value="1", name="a"), + SolidityValue(type="uint256", value="2", name="b"), + ], + ) + mock_api_clients.smart_contracts.read_contract = mock_read_contract + + result = SmartContract.read( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + method="pureTuple", + abi=all_read_types_abi, + ) + + assert result == {"a": 1, "b": 2} # In Python, we use regular integers, not BigInt + mock_read_contract.assert_called_once_with( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + read_contract_request=ANY, + ) + + +@patch("cdp.Cdp.api_clients") +def test_read_pure_tuple_mixed_types(mock_api_clients, all_read_types_abi): + """Test reading a tuple with mixed types from a pure function.""" + mock_read_contract = Mock() + mock_read_contract.return_value = SolidityValue( + type="tuple", + values=[ + SolidityValue(type="uint256", value="1", name="a"), + SolidityValue( + type="address", value="0x1234567890123456789012345678901234567890", name="b" + ), + SolidityValue(type="bool", value="true", name="c"), + ], + ) + mock_api_clients.smart_contracts.read_contract = mock_read_contract + + result = SmartContract.read( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + method="pureTupleMixedTypes", + abi=all_read_types_abi, + ) + + assert result == {"a": 1, "b": "0x1234567890123456789012345678901234567890", "c": True} + mock_read_contract.assert_called_once_with( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + read_contract_request=ANY, + ) + + +@patch("cdp.Cdp.api_clients") +def test_read_function_type_as_bytes(mock_api_clients, all_read_types_abi): + """Test reading a function type as bytes.""" + mock_read_contract = Mock() + mock_read_contract.return_value = SolidityValue( + type="bytes", value="0x12341234123412341234123400000000" + ) + mock_api_clients.smart_contracts.read_contract = mock_read_contract + + result = SmartContract.read( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + method="returnFunction", + abi=all_read_types_abi, + ) + + assert result == "0x12341234123412341234123400000000" + mock_read_contract.assert_called_once_with( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + read_contract_request=ANY, + ) + + +@patch("cdp.Cdp.api_clients") +def test_read_pure_nested_struct(mock_api_clients, all_read_types_abi): + """Test reading a nested struct from a pure function.""" + mock_read_contract = Mock() + mock_read_contract.return_value = SolidityValue( + type="tuple", + values=[ + SolidityValue(type="uint256", value="42", name="a"), + SolidityValue( + type="tuple", + name="nestedFields", + values=[ + SolidityValue( + type="tuple", + name="nestedArray", + values=[ + SolidityValue( + type="array", + name="a", + values=[ + SolidityValue(type="uint256", value="1"), + SolidityValue(type="uint256", value="2"), + SolidityValue(type="uint256", value="3"), + ], + ), + ], + ), + SolidityValue(type="uint256", value="123", name="a"), + ], + ), + ], + ) + mock_api_clients.smart_contracts.read_contract = mock_read_contract + + result = SmartContract.read( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + method="pureNestedStruct", + abi=all_read_types_abi, + ) + + assert result == { + "a": 42, + "nestedFields": { + "nestedArray": { + "a": [1, 2, 3], + }, + "a": 123, + }, + } + mock_read_contract.assert_called_once_with( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + read_contract_request=ANY, + ) + + +@patch("cdp.Cdp.api_clients") +def test_read_pure_string_without_abi(mock_api_clients): + """Test reading a string value from a pure function without an ABI.""" + mock_read_contract = Mock() + mock_read_contract.return_value = SolidityValue(type="string", value="Hello, World!") + mock_api_clients.smart_contracts.read_contract = mock_read_contract + + result = SmartContract.read( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + method="pureString", + ) + + assert result == "Hello, World!" + mock_read_contract.assert_called_once_with( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + read_contract_request=ANY, + ) + + +@patch("cdp.Cdp.api_clients") +def test_read_pure_bool_without_abi(mock_api_clients): + """Test reading a boolean value from a pure function without an ABI.""" + mock_read_contract = Mock() + mock_read_contract.return_value = SolidityValue(type="bool", value="true") + mock_api_clients.smart_contracts.read_contract = mock_read_contract + + result = SmartContract.read( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + method="pureBool", + ) + + assert result is True + mock_read_contract.assert_called_once_with( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + read_contract_request=ANY, + ) + + +@patch("cdp.Cdp.api_clients") +def test_read_pure_int8_without_abi(mock_api_clients): + """Test reading an int8 value from a pure function without an ABI.""" + mock_read_contract = Mock() + mock_read_contract.return_value = SolidityValue(type="int8", value="42") + mock_api_clients.smart_contracts.read_contract = mock_read_contract + + result = SmartContract.read( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + method="pureInt8", + ) + + assert result == 42 + mock_read_contract.assert_called_once_with( + network_id="1", + contract_address="0x1234567890123456789012345678901234567890", + read_contract_request=ANY, + ) From 5e2309af4b72bf8574fa989597c136780064a8f2 Mon Sep 17 00:00:00 2001 From: rohan-agarwal-coinbase Date: Thu, 17 Oct 2024 13:27:21 -0400 Subject: [PATCH 2/2] Update to 0.0.6 and update docs and changelog (#30) --- CHANGELOG.md | 2 ++ cdp/__version__.py | 2 +- docs/cdp.client.api.rst | 8 ++++++++ docs/cdp.client.models.rst | 32 ++++++++++++++++++++++++++++++++ docs/cdp.rst | 32 ++++++++++++++++++++++++++++++++ docs/conf.py | 2 +- pyproject.toml | 2 +- 7 files changed, 77 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a569d16..5a92322 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## [0.0.6] - 2024-10-17 + ### Added - Support for read_contract to read from smart contracts diff --git a/cdp/__version__.py b/cdp/__version__.py index b1a19e3..034f46c 100644 --- a/cdp/__version__.py +++ b/cdp/__version__.py @@ -1 +1 @@ -__version__ = "0.0.5" +__version__ = "0.0.6" diff --git a/docs/cdp.client.api.rst b/docs/cdp.client.api.rst index 7d27fa5..4a064c1 100644 --- a/docs/cdp.client.api.rst +++ b/docs/cdp.client.api.rst @@ -92,6 +92,14 @@ cdp.client.api.trades\_api module :undoc-members: :show-inheritance: +cdp.client.api.transaction\_history\_api module +----------------------------------------------- + +.. automodule:: cdp.client.api.transaction_history_api + :members: + :undoc-members: + :show-inheritance: + cdp.client.api.transfers\_api module ------------------------------------ diff --git a/docs/cdp.client.models.rst b/docs/cdp.client.models.rst index 4ff0b6f..1438528 100644 --- a/docs/cdp.client.models.rst +++ b/docs/cdp.client.models.rst @@ -212,6 +212,14 @@ cdp.client.models.create\_wallet\_request\_wallet module :undoc-members: :show-inheritance: +cdp.client.models.create\_wallet\_webhook\_request module +--------------------------------------------------------- + +.. automodule:: cdp.client.models.create_wallet_webhook_request + :members: + :undoc-members: + :show-inheritance: + cdp.client.models.create\_webhook\_request module ------------------------------------------------- @@ -348,6 +356,14 @@ cdp.client.models.historical\_balance module :undoc-members: :show-inheritance: +cdp.client.models.multi\_token\_contract\_options module +-------------------------------------------------------- + +.. automodule:: cdp.client.models.multi_token_contract_options + :members: + :undoc-members: + :show-inheritance: + cdp.client.models.network module -------------------------------- @@ -388,6 +404,14 @@ cdp.client.models.payload\_signature\_list module :undoc-members: :show-inheritance: +cdp.client.models.read\_contract\_request module +------------------------------------------------ + +.. automodule:: cdp.client.models.read_contract_request + :members: + :undoc-members: + :show-inheritance: + cdp.client.models.seed\_creation\_event module ---------------------------------------------- @@ -500,6 +524,14 @@ cdp.client.models.smart\_contract\_type module :undoc-members: :show-inheritance: +cdp.client.models.solidity\_value module +---------------------------------------- + +.. automodule:: cdp.client.models.solidity_value + :members: + :undoc-members: + :show-inheritance: + cdp.client.models.sponsored\_send module ---------------------------------------- diff --git a/docs/cdp.rst b/docs/cdp.rst index 2692f8f..ca117b5 100644 --- a/docs/cdp.rst +++ b/docs/cdp.rst @@ -92,6 +92,38 @@ cdp.faucet\_transaction module :undoc-members: :show-inheritance: +cdp.hash\_utils module +---------------------- + +.. automodule:: cdp.hash_utils + :members: + :undoc-members: + :show-inheritance: + +cdp.historical\_balance module +------------------------------ + +.. automodule:: cdp.historical_balance + :members: + :undoc-members: + :show-inheritance: + +cdp.payload\_signature module +----------------------------- + +.. automodule:: cdp.payload_signature + :members: + :undoc-members: + :show-inheritance: + +cdp.smart\_contract module +-------------------------- + +.. automodule:: cdp.smart_contract + :members: + :undoc-members: + :show-inheritance: + cdp.sponsored\_send module -------------------------- diff --git a/docs/conf.py b/docs/conf.py index c437b96..59a0c90 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -14,7 +14,7 @@ project = 'CDP SDK' author = 'Coinbase Developer Platform' -release = '0.0.5' +release = '0.0.6' # -- General configuration --------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration diff --git a/pyproject.toml b/pyproject.toml index 42b1a6a..32bcc20 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "cdp-sdk" -version = "0.0.5" +version = "0.0.6" description = "CDP Python SDK" readme = "README.md" authors = [{name = "John Peterson", email = "john.peterson@coinbase.com"}]