diff --git a/docs/contract.rst b/docs/contract.rst index d60077c4b..1611d0e33 100644 --- a/docs/contract.rst +++ b/docs/contract.rst @@ -12,7 +12,7 @@ Contract .. autoclass:: PreparedFunctionCall :exclude-members: __init__, __new__ - :members: call, call_raw, invoke, call_sync, call_raw_sync, invoke_sync, hash, estimate_fee, estimate_fee_sync + :members: call, call_raw, invoke, call_sync, call_raw_sync, invoke_sync, estimate_fee, estimate_fee_sync .. autoclass:: InvokeResult :exclude-members: __init__, __new__ diff --git a/docs/guide.rst b/docs/guide.rst index 5686977f7..5f44d01a0 100644 --- a/docs/guide.rst +++ b/docs/guide.rst @@ -46,7 +46,7 @@ signing algorithm, it is possible to create ``AccountClient`` with custom .. literalinclude:: ../starknet_py/tests/e2e/docs/guide/test_custom_signer.py :language: python - :lines: 11-33 + :lines: 11-35 :dedent: 4 diff --git a/poetry.lock b/poetry.lock index 024f53947..088e1ddea 100644 --- a/poetry.lock +++ b/poetry.lock @@ -318,7 +318,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" [[package]] name = "coverage" -version = "6.4.2" +version = "6.4.3" description = "Code coverage measurement for Python" category = "dev" optional = false @@ -709,7 +709,7 @@ python-versions = "*" [[package]] name = "frozenlist" -version = "1.3.0" +version = "1.3.1" description = "A list-like structure which implements collections.abc.MutableSequence" category = "main" optional = false @@ -731,17 +731,17 @@ tornado = ["tornado (>=0.2)"] [[package]] name = "hexbytes" -version = "0.2.2" +version = "0.2.3" description = "hexbytes: Python `bytes` subclass that decodes hex, with a readable console output" category = "main" optional = false python-versions = ">=3.6, <4" [package.extras] -test = ["tox (==3.14.6)", "pytest (==5.4.1)", "pytest-xdist", "hypothesis (>=3.44.24,<4)", "eth-utils (>=1.0.1,<2)"] -lint = ["pydocstyle (>=5.0.0,<6)", "mypy (==0.770)", "isort (>=4.2.15,<5)", "flake8 (==3.7.9)"] -doc = ["towncrier (>=19.2.0,<20)", "sphinx-rtd-theme (>=0.1.9,<1)", "Sphinx (>=1.6.5,<2)"] -dev = ["wheel", "twine", "tox (==3.14.6)", "towncrier (>=19.2.0,<20)", "sphinx-rtd-theme (>=0.1.9,<1)", "pytest (==5.4.1)", "pytest-xdist", "pytest-watch (>=4.1.0,<5)", "pydocstyle (>=5.0.0,<6)", "mypy (==0.770)", "isort (>=4.2.15,<5)", "ipython", "hypothesis (>=3.44.24,<4)", "flake8 (==3.7.9)", "eth-utils (>=1.0.1,<2)", "bumpversion (>=0.5.3,<1)", "Sphinx (>=1.6.5,<2)"] +test = ["eth-utils (>=1.0.1,<2)", "hypothesis (>=3.44.24,<=6.31.6)", "tox (>=3.25.1,<4)", "pytest-xdist", "pytest (>=7,<8)"] +lint = ["black (>=22,<23)", "pydocstyle (>=5.0.0,<6)", "mypy (==0.971)", "isort (>=4.2.15,<5)", "flake8 (==3.7.9)"] +doc = ["jinja2 (>=3.0.0,<3.1.0)", "towncrier (>=21,<22)", "sphinx-rtd-theme (>=0.1.9,<1)", "Sphinx (>=1.6.5,<2)"] +dev = ["jinja2 (>=3.0.0,<3.1.0)", "towncrier (>=21,<22)", "sphinx-rtd-theme (>=0.1.9,<1)", "Sphinx (>=1.6.5,<2)", "black (>=22,<23)", "pydocstyle (>=5.0.0,<6)", "mypy (==0.971)", "isort (>=4.2.15,<5)", "flake8 (==3.7.9)", "eth-utils (>=1.0.1,<2)", "hypothesis (>=3.44.24,<=6.31.6)", "tox (>=3.25.1,<4)", "pytest-xdist", "pytest (>=7,<8)", "ipython", "twine", "wheel", "pytest-watch (>=4.1.0,<5)", "bumpversion (>=0.5.3,<1)"] [[package]] name = "html5lib" @@ -867,7 +867,7 @@ i18n = ["Babel (>=2.7)"] [[package]] name = "jsonschema" -version = "4.9.0" +version = "4.9.1" description = "An implementation of JSON Schema validation for Python" category = "main" optional = false @@ -882,8 +882,8 @@ pyrsistent = ">=0.14.0,<0.17.0 || >0.17.0,<0.17.1 || >0.17.1,<0.17.2 || >0.17.2" typing-extensions = {version = "*", markers = "python_version < \"3.8\""} [package.extras] -format = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3987", "uri-template", "webcolors (>=1.11)"] -format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "uri-template", "webcolors (>=1.11)"] +format-nongpl = ["webcolors (>=1.11)", "uri-template", "rfc3986-validator (>0.1.0)", "rfc3339-validator", "jsonpointer (>1.13)", "isoduration", "idna", "fqdn"] +format = ["webcolors (>=1.11)", "uri-template", "rfc3987", "rfc3339-validator", "jsonpointer (>1.13)", "isoduration", "idna", "fqdn"] [[package]] name = "lark-parser" @@ -1425,7 +1425,7 @@ testing = ["filelock"] [[package]] name = "pytz" -version = "2022.1" +version = "2022.2" description = "World timezone definitions, modern and historical" category = "main" optional = false diff --git a/requirements.txt b/requirements.txt index 085d0fbae..08ac7fbb2 100644 --- a/requirements.txt +++ b/requirements.txt @@ -36,8 +36,8 @@ eth-typing==3.1.0; python_version >= "3.7" and python_version < "3.11" and pytho eth-utils==2.0.0; python_version >= "3.7" and python_version < "3.11" and python_full_version >= "3.7.2" fastecdsa==2.2.3; python_version >= "3.6" and python_full_version >= "3.7.2" frozendict==1.2; python_version >= "3.6" and python_full_version >= "3.7.2" -frozenlist==1.3.0; python_version >= "3.7" and python_full_version >= "3.7.2" and python_version < "3.11" -hexbytes==0.2.2; python_version >= "3.7" and python_version < "3.11" and python_full_version >= "3.7.2" +frozenlist==1.3.1; python_version >= "3.7" and python_full_version >= "3.7.2" and python_version < "3.11" +hexbytes==0.2.3; python_version >= "3.7" and python_version < "3.11" and python_full_version >= "3.7.2" html5lib==1.1; python_version >= "3.7" and python_full_version < "3.0.0" or python_version >= "3.7" and python_full_version >= "3.5.0" idna==3.3; python_version >= "3.7" and python_version < "3.11" and python_full_version >= "3.7.2" imagesize==1.4.1; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version >= "3.6" @@ -46,7 +46,7 @@ importlib-resources==5.9.0; python_full_version >= "3.7.2" and python_version < iniconfig==1.1.1; python_version >= "3.6" and python_full_version >= "3.7.2" ipfshttpclient==0.8.0a2; python_full_version >= "3.7.2" and python_version < "3.11" and python_version >= "3.6" jinja2==3.1.2; python_version >= "3.7" -jsonschema==4.9.0; python_full_version >= "3.7.2" and python_version < "3.11" and python_version >= "3.7" +jsonschema==4.9.1; python_full_version >= "3.7.2" and python_version < "3.11" and python_version >= "3.7" lark-parser==0.12.0; python_version >= "3.6" and python_full_version >= "3.7.2" lockfile==0.12.2 lru-dict==1.1.8; python_full_version >= "3.7.2" and python_version < "3.11" and python_version >= "3.6" @@ -78,7 +78,7 @@ pyparsing==3.0.9; python_version >= "3.7" and python_full_version >= "3.7.2" pyrsistent==0.18.1; python_full_version >= "3.7.2" and python_version < "3.11" and python_version >= "3.7" pytest-asyncio==0.16.0; python_version >= "3.6" pytest==6.2.5; python_version >= "3.6" -pytz==2022.1; python_version >= "3.6" +pytz==2022.2; python_version >= "3.6" pywin32==304; python_full_version >= "3.7.2" and python_version < "3.11" and platform_system == "Windows" and python_version >= "3.6" pyyaml==6.0; python_version >= "3.6" and python_full_version >= "3.7.2" requests==2.28.1; python_version >= "3.7" and python_version < "3.11" and python_full_version >= "3.7.2" diff --git a/starknet_py/contract.py b/starknet_py/contract.py index 7802dd085..8ad7417d0 100644 --- a/starknet_py/contract.py +++ b/starknet_py/contract.py @@ -2,7 +2,6 @@ import dataclasses import sys -import warnings from dataclasses import dataclass from typing import ( List, @@ -32,7 +31,6 @@ AddressRepresentation, parse_address, compute_address, - compute_invoke_hash, ) from starknet_py.compile.compiler import StarknetCompilationSource from starknet_py.transactions.deploy import make_deploy_tx @@ -150,19 +148,6 @@ def __init__( self.max_fee = max_fee self.version = version - @property - def hash(self) -> int: - warnings.warn("Hash is deprecated and will be deleted in next releases") - - return compute_invoke_hash( - contract_address=self._contract_data.address, - entry_point_selector=self.selector, - calldata=self.calldata, - chain_id=self._client.chain, - max_fee=self.max_fee if self.max_fee is not None else 0, - version=self.version, - ) - async def call_raw( self, signature: Optional[Collection[int]] = None, diff --git a/starknet_py/contract_test.py b/starknet_py/contract_test.py index 89be99920..e3f5f5ffb 100644 --- a/starknet_py/contract_test.py +++ b/starknet_py/contract_test.py @@ -1,7 +1,6 @@ import pytest -from starknet_py.contract import Contract, PreparedFunctionCall, ContractData -from starknet_py.net.gateway_client import GatewayClient +from starknet_py.contract import Contract from starknet_py.tests.e2e.conftest import directory_with_contracts SOURCE = """ @@ -119,24 +118,6 @@ def test_compute_address_throws_on_no_source(): ) -def test_transaction_hash(): - call = PreparedFunctionCall( - calldata=[1234], - arguments={}, - selector=1530486729947006463063166157847785599120665941190480211966374137237989315360, - client=GatewayClient("testnet"), - payload_transformer=None, - contract_data=ContractData( - address=0x03606DB92E563E41F4A590BC01C243E8178E9BA8C980F8E464579F862DA3537C, - abi=None, - identifier_manager=None, - ), - version=0, - max_fee=0, - ) - assert call.hash == 0xD0A52D6E77B836613B9F709AD7F4A88297697FEFBEF1ADA3C59692FF46702C - - def test_no_valid_source(): with pytest.raises(ValueError) as v_err: Contract.compute_contract_hash() diff --git a/starknet_py/net/account/account_client.py b/starknet_py/net/account/account_client.py index e7a8801d8..53b494c6a 100644 --- a/starknet_py/net/account/account_client.py +++ b/starknet_py/net/account/account_client.py @@ -72,7 +72,7 @@ def __init__( "Either a signer or a key_pair must be provided in AccountClient constructor" ) - if chain is None and client.chain is None and signer is None: + if chain is None and signer is None and client.chain is None: raise ValueError("One of chain or signer must be provided") self.address = parse_address(address) @@ -274,12 +274,6 @@ async def _get_max_fee( if max_fee is None: raise ValueError("Max_fee must be specified when invoking a transaction") - if max_fee == 0: - warnings.warn( - "Transaction will fail with max_fee set to 0. Change it to a higher value.", - DeprecationWarning, - ) - return max_fee async def sign_transaction( @@ -310,6 +304,12 @@ async def sign_transaction( async def send_transaction( self, transaction: InvokeFunction ) -> SentTransactionResponse: + if transaction.max_fee == 0: + warnings.warn( + "Transaction will fail with max_fee set to 0. Change it to a higher value.", + DeprecationWarning, + ) + return await self.client.send_transaction(transaction=transaction) async def execute( @@ -382,7 +382,7 @@ async def create_account( :param chain: ChainId of the chain used to create the default signer :return: Instance of AccountClient which interacts with created account on given network """ - if chain is None and client.chain is None and signer is None: + if chain is None and signer is None and client.chain is None: raise ValueError("One of chain or signer must be provided") if signer is None: diff --git a/starknet_py/net/full_node_client.py b/starknet_py/net/full_node_client.py index 9f2ab03d3..aca018247 100644 --- a/starknet_py/net/full_node_client.py +++ b/starknet_py/net/full_node_client.py @@ -65,7 +65,11 @@ def __init__( """ self.url = node_url self._client = RpcHttpClient(url=node_url, session=session) - self._chain = chain_from_network(net, chain) + + if net in ["testnet", "mainnet"]: + chain = chain_from_network(net, chain) + self._chain = chain + self._net = net @property diff --git a/starknet_py/net/gateway_client.py b/starknet_py/net/gateway_client.py index 2f3b432e3..d766ba9ad 100644 --- a/starknet_py/net/gateway_client.py +++ b/starknet_py/net/gateway_client.py @@ -76,7 +76,11 @@ def __init__( gateway_url = net["gateway_url"] self._net = net - self._chain = chain_from_network(net, chain) + + if net in ["testnet", "mainnet"]: + chain = chain_from_network(net, chain) + self._chain = chain + self._feeder_gateway_client = GatewayHttpClient( url=feeder_gateway_url, session=session ) diff --git a/starknet_py/net/gateway_schemas/gateway_schemas.py b/starknet_py/net/gateway_schemas/gateway_schemas.py index e96af10ee..029aab946 100644 --- a/starknet_py/net/gateway_schemas/gateway_schemas.py +++ b/starknet_py/net/gateway_schemas/gateway_schemas.py @@ -123,7 +123,7 @@ class TransactionReceiptSchema(Schema): values=fields.Raw(), data_key="transaction_failure_reason", allow_none=True, - default=None, + load_default=None, ) events = fields.List( fields.Nested(EventSchema()), data_key="events", load_default=[] diff --git a/starknet_py/tests/e2e/account/account_client_test.py b/starknet_py/tests/e2e/account/account_client_test.py index 921418ece..277f25bea 100644 --- a/starknet_py/tests/e2e/account/account_client_test.py +++ b/starknet_py/tests/e2e/account/account_client_test.py @@ -84,9 +84,7 @@ async def test_estimate_fee_called(erc20_contract): mocked_estimate_fee.return_value = result - await erc20_contract.functions["balanceOf"].prepare( - "1234", max_fee=0 - ).estimate_fee() + await erc20_contract.functions["balanceOf"].prepare("1234").estimate_fee() mocked_estimate_fee.assert_called() @@ -94,9 +92,7 @@ async def test_estimate_fee_called(erc20_contract): @pytest.mark.asyncio async def test_estimated_fee_greater_than_zero(erc20_contract): estimated_fee = ( - await erc20_contract.functions["balanceOf"] - .prepare("1234", max_fee=0) - .estimate_fee() + await erc20_contract.functions["balanceOf"].prepare("1234").estimate_fee() ) assert estimated_fee.overall_fee > 0 @@ -132,7 +128,6 @@ async def test_create_account_client_with_signer(run_devnet): key_pair = KeyPair.from_private_key(1234) client = GatewayClient( net=run_devnet, - chain=StarknetChainId.TESTNET, ) address = await deploy_account_contract( client=client, diff --git a/starknet_py/tests/e2e/client/client_test.py b/starknet_py/tests/e2e/client/client_test.py index 9560447ed..817007236 100644 --- a/starknet_py/tests/e2e/client/client_test.py +++ b/starknet_py/tests/e2e/client/client_test.py @@ -7,7 +7,6 @@ from starkware.starknet.public.abi import get_selector_from_name from starkware.starknet.services.api.gateway.transaction import DECLARE_SENDER_ADDRESS -from starknet_py.net.models import StarknetChainId from starknet_py.net.client_models import ( TransactionStatus, InvokeFunction, @@ -349,11 +348,6 @@ async def test_get_class_by_hash(clients, class_hash): assert contract_class.entry_points_by_type is not None -def test_chain_id(clients): - for client in clients: - assert client.chain == StarknetChainId.TESTNET - - @pytest.mark.asyncio async def test_wait_for_tx_accepted(gateway_client): with patch( diff --git a/starknet_py/tests/e2e/client/gateway_test.py b/starknet_py/tests/e2e/client/gateway_test.py index c68a7cf21..0bb0a15c5 100644 --- a/starknet_py/tests/e2e/client/gateway_test.py +++ b/starknet_py/tests/e2e/client/gateway_test.py @@ -2,7 +2,6 @@ from starknet_py.net.client_models import TransactionStatusResponse, TransactionStatus from starknet_py.net.gateway_client import GatewayClient -from starknet_py.net.models import StarknetChainId from starknet_py.net.networks import TESTNET, MAINNET @@ -54,29 +53,27 @@ async def test_get_transaction_status(invoke_transaction_hash, gateway_client): # pylint: disable=protected-access @pytest.mark.parametrize( - "net, net_address, chain", + "net, net_address", ( - (TESTNET, "https://alpha4.starknet.io", StarknetChainId.TESTNET), - (MAINNET, "https://alpha-mainnet.starknet.io", StarknetChainId.MAINNET), + (TESTNET, "https://alpha4.starknet.io"), + (MAINNET, "https://alpha-mainnet.starknet.io"), ), ) -def test_creating_client_from_predefined_network(net, net_address, chain): +def test_creating_client_from_predefined_network(net, net_address): gateway_client = GatewayClient(net=net) assert gateway_client.net == net assert gateway_client._feeder_gateway_client.url == f"{net_address}/feeder_gateway" assert gateway_client._gateway_client.url == f"{net_address}/gateway" - assert gateway_client.chain == chain def test_creating_client_with_custom_net(): custom_net = "custom.net" - gateway_client = GatewayClient(net=custom_net, chain=StarknetChainId.TESTNET) + gateway_client = GatewayClient(net=custom_net) assert gateway_client.net == custom_net assert gateway_client._feeder_gateway_client.url == f"{custom_net}/feeder_gateway" assert gateway_client._gateway_client.url == f"{custom_net}/gateway" - assert gateway_client.chain == StarknetChainId.TESTNET def test_creating_client_with_custom_net_dict(): @@ -86,26 +83,8 @@ def test_creating_client_with_custom_net_dict(): "gateway_url": f"{custom_net}/gateway", } - gateway_client = GatewayClient(net=net, chain=StarknetChainId.TESTNET) + gateway_client = GatewayClient(net=net) assert gateway_client.net == net assert gateway_client._feeder_gateway_client.url == net["feeder_gateway_url"] assert gateway_client._gateway_client.url == net["gateway_url"] - assert gateway_client.chain == StarknetChainId.TESTNET - - -@pytest.mark.parametrize( - "net", - ( - { - "feeder_gateway_url": "custom.net/feeder_gateway", - "gateway_url": "custom.net/gateway", - }, - "custom.net", - ), -) -def test_throwing_on_custom_net_without_chain(net): - with pytest.raises(ValueError) as err: - GatewayClient(net=net) - - assert "Chain is required when not using predefined networks." == str(err.value) diff --git a/starknet_py/tests/e2e/conftest.py b/starknet_py/tests/e2e/conftest.py index 5a740b93b..8df970ec4 100644 --- a/starknet_py/tests/e2e/conftest.py +++ b/starknet_py/tests/e2e/conftest.py @@ -103,14 +103,12 @@ def create_gateway_client(pytestconfig, run_devnet): "integration": "https://external.integration.starknet.io", } - return GatewayClient(net=net_address[net], chain=StarknetChainId.TESTNET) + return GatewayClient(net=net_address[net]) @pytest.fixture(name="rpc_client", scope="module") def create_rpc_client(run_devnet): - return FullNodeClient( - node_url=run_devnet + "/rpc", chain=StarknetChainId.TESTNET, net=run_devnet - ) + return FullNodeClient(node_url=run_devnet + "/rpc", net=run_devnet) def create_account_client( @@ -121,6 +119,7 @@ def create_account_client( address=address, client=gateway_client, key_pair=key_pair, + chain=StarknetChainId.TESTNET, ) diff --git a/starknet_py/tests/e2e/docs/guide/test_account_client_details.py b/starknet_py/tests/e2e/docs/guide/test_account_client_details.py index 05da5bd67..03ea036bd 100644 --- a/starknet_py/tests/e2e/docs/guide/test_account_client_details.py +++ b/starknet_py/tests/e2e/docs/guide/test_account_client_details.py @@ -19,7 +19,7 @@ async def test_account_client_details( # Creates an account client = await AccountClient.create_account( - client=GatewayClient(net=net, chain=StarknetChainId.TESTNET) + client=GatewayClient(net=net), chain=StarknetChainId.TESTNET ) # add to docs: end diff --git a/starknet_py/tests/e2e/docs/guide/test_custom_signer.py b/starknet_py/tests/e2e/docs/guide/test_custom_signer.py index 3dc7e6a71..7b55db762 100644 --- a/starknet_py/tests/e2e/docs/guide/test_custom_signer.py +++ b/starknet_py/tests/e2e/docs/guide/test_custom_signer.py @@ -12,6 +12,7 @@ async def test_custom_signer(): from starknet_py.net.signer import BaseSigner from starknet_py.net.gateway_client import GatewayClient from starknet_py.net.models import Transaction + from starknet_py.net.models import StarknetChainId # Create a custom signer class implementing BaseSigner interface class CustomSigner(BaseSigner): @@ -29,6 +30,7 @@ def sign_transaction(self, transaction: Transaction) -> List[int]: client=client, address=0x1111, signer=custom_signer, + chain=StarknetChainId.TESTNET, ) # Now you can use AccountClient as you'd always do # add to docs: end diff --git a/starknet_py/tests/e2e/docs/guide/test_using_cairo_serializer.py b/starknet_py/tests/e2e/docs/guide/test_using_cairo_serializer.py index f31324d1d..e6a2a4e72 100644 --- a/starknet_py/tests/e2e/docs/guide/test_using_cairo_serializer.py +++ b/starknet_py/tests/e2e/docs/guide/test_using_cairo_serializer.py @@ -47,7 +47,7 @@ async def test_using_cairo_serializer(run_devnet, gateway_account_client): # Creates an account client = await AccountClient.create_account( - client=GatewayClient(net=net, chain=StarknetChainId.TESTNET), + client=GatewayClient(net=net), chain=StarknetChainId.TESTNET, ) # add to docs: end diff --git a/starknet_py/tests/e2e/docs/quickstart/test_creating_account_client.py b/starknet_py/tests/e2e/docs/quickstart/test_creating_account_client.py index 971ccab58..9490e3278 100644 --- a/starknet_py/tests/e2e/docs/quickstart/test_creating_account_client.py +++ b/starknet_py/tests/e2e/docs/quickstart/test_creating_account_client.py @@ -18,7 +18,7 @@ async def test_creating_account_client(run_devnet): # add to docs: start # Creates an instance of account client which is already deployed (testnet): - client = GatewayClient(net=testnet, chain=chain_id) + client = GatewayClient(net=testnet) account_client_testnet = AccountClient( client=client, address="0x1234", diff --git a/starknet_py/tests/e2e/docs/quickstart/test_using_account_client.py b/starknet_py/tests/e2e/docs/quickstart/test_using_account_client.py index b9b5ad892..2328cc04e 100644 --- a/starknet_py/tests/e2e/docs/quickstart/test_using_account_client.py +++ b/starknet_py/tests/e2e/docs/quickstart/test_using_account_client.py @@ -20,9 +20,9 @@ async def test_using_account_client( # add to docs: start # Creates an account on testnet and returns an instance - client = GatewayClient(net=testnet, chain=StarknetChainId.TESTNET) + client = GatewayClient(net=testnet) acc_client = await AccountClient.create_account( - client=client, chain=StarknetChainId + client=client, chain=StarknetChainId.TESTNET ) # add to docs: end acc_client = gateway_account_client