Skip to content

Commit

Permalink
Deprecate v1 and v2 transactions (#1545)
Browse files Browse the repository at this point in the history
* Remove v1 and v2 txs examples from docs

* Temporarily add `verbose` flag when installing poetry

* Fix command

* Remove `poetry config installer.modern-installation false`

* Use `poetry check --lock` instead of `poetry lock --check`

* Update `pyproject.toml` to remove poetry deprecation warnings

* Temporarily add `poetry --version`

* Set poetry version to `1.8.5`

* Temporarily bring back poetry to latest version

* Revert "Temporarily bring back poetry to latest version"

This reverts commit d8cab89.

* Remove unnecessarily introduced CI changes

* Remove changes in `pyproject.toml`

* Increase resource bounds in `test_simple_declare_and_deploy`

* Use latest poetry; Require python >= 3.9

* Run `poetry lock --no-update`

* Remove poetry configuration of `modern-installation`

* Add `poetry self add poetry-plugin-export` in docs workflow

* Update migration guide

* Trigger CI

* Fix `test_signing_fee_estimate`

* Fix `test_deploy_prefunded_account`

* Update `pyproject.toml` and `poetry.lock`

* Update dependencies versions

* Update license to TOML format

* Update `[project]` and `[tool.poetry]`

* Use `[project.urls]`

* Remove changes in `checks.yml`

* Mark `test_account_outside_execution_any_caller` as skipped; Add todo

* Fix test skipping

* Fix linting

* Fix linting

* Fix failing `test_simple_declare_and_deploy`

* Fix other failing tests

* Fix formatting

* Deprecate v1, v2 methods and classes

* Format

* Minor fixes

* Fix linting

* Fix formatting

* Fix typechecking

* Fix formatting

* Fix linting

* Bump artifact actions to v4

* Trigger CI

* Fix docs building

* Make wrapper private

* Fic formatting

* Use deprecation util function instead of decorator

* Fix failing test

* Fix linting

* Fix failing tests

* Change version from which v1 and v2 txs are deprecated

* Set `stacklevel` to 3

* Deprecate `DeclareResult.deploy_v1`

* Use v3 in `test_account_sign_without_execute`

* Update development guide

* Use `typing_extensions.deprecated` instead of custom function

* Temporarily remove increasing account balance in `full_node_account` fixture

* Fix linting

* Temporarily remove increasing account balance in fixture

* Use `deprecated` library

* Fix linting

* Bring back util function for deprecation warnings

* Remove setting warnings filter

* Restore increasing account balance in `full_node_account` fixture

* Remove `Deprecated` package

* Update `pyproject.toml`

* Decrease `max_amount` in `test_simple_declare_and_deploy`

* Fix failing tests

* Remove unnecessary code

* Remove transfer transaction; Add minor fixes

* Fix linting
  • Loading branch information
franciszekjob authored Jan 13, 2025
1 parent c878d07 commit 2478a6c
Show file tree
Hide file tree
Showing 35 changed files with 364 additions and 162 deletions.
19 changes: 15 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ It supports an account contract which proxies the calls to other contracts on St

Account can be created in two ways:
- By constructor (It is required to provide an `address` and either `key_pair` or `signer`).
- By static methods `Account.deploy_account_v1` or `Account.deploy_account_v3`
- By static method `Account.deploy_account_v3`

Additionally, you can use the [sncast](https://foundry-rs.github.io/starknet-foundry/starknet/index.html) tool to create an account,
which will automatically be saved to a file.
Expand Down Expand Up @@ -159,6 +159,7 @@ await account.client.wait_for_tx(transaction_response.transaction_hash)
[Contract](https://starknetpy.readthedocs.io/en/latest/api/contract.html#starknet_py.contract.Contract) makes interacting with contracts deployed on Starknet much easier:
```python
from starknet_py.contract import Contract
from starknet_py.net.client_models import ResourceBounds

contract_address = (
"0x01336fa7c870a7403aced14dda865b75f29113230ed84e3a661f7af70fe83e7b"
Expand All @@ -178,8 +179,13 @@ contract = Contract(

# All exposed functions are available at contract.functions.
# Here we invoke a function, creating a new transaction.
invocation = await contract.functions["put"].invoke_v1(key, 7, max_fee=int(1e16))

invocation = await contract.functions["put"].invoke_v3(
key,
7,
l1_resource_bounds=ResourceBounds(
max_amount=int(1e5), max_price_per_unit=int(1e13)
),
)
# Invocation returns InvokeResult object. It exposes a helper for waiting until transaction is accepted.
await invocation.wait_for_acceptance()

Expand All @@ -194,6 +200,7 @@ Although asynchronous API is recommended, you can also use Contract’s synchron

```python
from starknet_py.contract import Contract
from starknet_py.net.client_models import ResourceBounds

contract_address = (
"0x01336fa7c870a7403aced14dda865b75f29113230ed84e3a661f7af70fe83e7b"
Expand All @@ -202,7 +209,11 @@ contract_address = (
key = 1234
contract = Contract.from_address_sync(address=contract_address, provider=account)

invocation = contract.functions["put"].invoke_v1_sync(key, 7, max_fee=int(1e16))
l1_resource_bounds = ResourceBounds(
max_amount=int(1e5), max_price_per_unit=int(1e13)
),

invocation = contract.functions["put"].invoke_v3_sync(key, 7, l1_resource_bounds=l1_resource_bounds)
invocation.wait_for_acceptance_sync()

(saved,) = contract.functions["get"].call_sync(key) # 7
Expand Down
3 changes: 1 addition & 2 deletions docs/account_creation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,5 @@ Here is step by step example:

If you are experiencing transaction failures with ``FEE_TRANSFER_FAILURE``
make sure that the address you are trying to deploy is prefunded with enough
tokens, and verify that ``max_fee`` argument in :meth:`~starknet_py.net.account.account.Account.sign_deploy_account_v1`
or ``l1_resource_bounds`` argument in :meth:`~starknet_py.net.account.account.Account.sign_deploy_account_v3` is set
tokens, and verify that ``l1_resource_bounds`` argument in :meth:`~starknet_py.net.account.account.Account.sign_deploy_account_v3` is set
to a high enough value.
16 changes: 6 additions & 10 deletions docs/guide/account_and_client.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ Account and Client
Executing transactions
----------------------

To execute transactions on Starknet, use :meth:`~starknet_py.net.account.account.Account.execute_v1` or :meth:`~starknet_py.net.account.account.Account.execute_v3` methods from :ref:`Account` interface.
These methods will send :class:`~starknet_py.net.models.InvokeV1` and :class:`~starknet_py.net.models.InvokeV3` transactions respectively. To read about differences between transaction versions please visit `transaction types <https://docs.starknet.io/documentation/architecture_and_concepts/Network_Architecture/transactions>`_ from the Starknet docs.
To execute transactions on Starknet, use :meth:`~starknet_py.net.account.account.Account.execute_v3` method from :ref:`Account` interface, which will send :class:`~starknet_py.net.models.InvokeV3` transaction.

.. codesnippet:: ../../starknet_py/tests/e2e/docs/guide/test_executing_transactions.py
:language: python
Expand All @@ -15,25 +14,22 @@ Transaction Fee
---------------

All methods within the :ref:`Account` that involve on-chain modifications require either specifying a maximum transaction fee or using auto estimation.
In the case of V1 and V2 transactions, the transaction fee, denoted in Wei, is configured by the ``max_fee`` parameter.
For V3 transactions, however, the fee is expressed in Fri and is determined by the ``l1_resource_bounds`` parameter.
For V3 transaction, the fee is expressed in Fri and is determined by the ``l1_resource_bounds`` parameter.
To enable auto estimation, set the ``auto_estimate`` parameter to ``True``.

.. code-block:: python
resp = await account.execute_v1(calls=call, auto_estimate=True)
resp = await account.execute_v3(calls=call, auto_estimate=True)
.. warning::

It is strongly discouraged to use automatic fee estimation in production code as it may lead to an unexpectedly high fee.

The returned estimated fee is multiplied by ``1.5`` for V1 and V2 transactions to mitigate fluctuations in price.
For V3 transactions, ``max_amount`` and ``max_price_per_unit`` are scaled by ``1.5`` and ``1.5`` respectively.
The returned estimated fee (``max_amount`` and ``max_price_per_unit``) is multiplied by ``1.5`` to mitigate fluctuations in price.

.. note::
It is possible to configure the value by which the estimated fee is multiplied,
by changing ``ESTIMATED_FEE_MULTIPLIER`` for V1 and V2 transactions in :class:`~starknet_py.net.account.account.Account`.
The same applies to ``ESTIMATED_AMOUNT_MULTIPLIER`` and ``ESTIMATED_UNIT_PRICE_MULTIPLIER`` for V3 transactions.
by changing ``ESTIMATED_AMOUNT_MULTIPLIER`` and ``ESTIMATED_UNIT_PRICE_MULTIPLIER`` in :class:`~starknet_py.net.account.account.Account`.

The fee for a specific transaction or list of transactions can be also estimated using the :meth:`~starknet_py.net.account.account.Account.estimate_fee` of the :ref:`Account` class.

Expand Down Expand Up @@ -61,7 +57,7 @@ Multicall
---------

There is a possibility to execute an Invoke transaction containing multiple calls.
Simply pass a list of calls to :meth:`~starknet_py.net.account.account.Account.execute_v1` or :meth:`~starknet_py.net.account.account.Account.execute_v3` methods.
Simply pass a list of calls to :meth:`~starknet_py.net.account.account.Account.execute_v3` method.
Note that the nonce will be bumped only by 1.

.. codesnippet:: ../../starknet_py/tests/e2e/docs/guide/test_multicall.py
Expand Down
8 changes: 4 additions & 4 deletions docs/guide/deploying_contracts.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ Deploying contracts
Declaring contracts
-------------------

A declare transaction can be issued in version 2 or 3. Contracts written in Cairo 0 cannot be declared while those written in Cairo 1 or higher should be declared with versions 2 or 3.
To sign a declare transaction, you should utilize the :meth:`~starknet_py.net.account.account.Account.sign_declare_v2` or :meth:`~starknet_py.net.account.account.Account.sign_declare_v3` method, respectively.
Contracts written in Cairo 0 cannot be declared while those written in Cairo 1 or higher should be declared with transaction version 3.
To sign a declare transaction, you should utilize :meth:`~starknet_py.net.account.account.Account.sign_declare_v3` method.

Here's an example how to use it.

Expand All @@ -17,7 +17,7 @@ Here's an example how to use it.
Simple deploy
-------------

If you know the class hash of an already declared contract you want to deploy just use the :meth:`~starknet_py.contract.Contract.deploy_contract_v1` or :meth:`~starknet_py.contract.Contract.deploy_contract_v3`.
If you know the class hash of an already declared contract you want to deploy just use the :meth:`~starknet_py.contract.Contract.deploy_contract_v3`.
It will deploy the contract using funds from your account. Deployment is handled by UDC.

.. codesnippet:: ../../starknet_py/tests/e2e/docs/guide/test_simple_deploy.py
Expand Down Expand Up @@ -57,7 +57,7 @@ Cairo1 contracts
Declaring Cairo1 contracts
##########################

To declare a contract in Cairo version 1 or higher, Declare V2 or Declare V3 transaction has to be sent.
To declare a contract in Cairo version 1 or higher, Declare V3 transaction has to be sent.
You can see the structure of these transactions `here <https://docs.starknet.io/documentation/architecture_and_concepts/Network_Architecture/transactions/#declare-transaction>`_.

The main differences in the structure of the transaction from its previous version are:
Expand Down
40 changes: 21 additions & 19 deletions docs/guide/using_existing_contracts.rst
Original file line number Diff line number Diff line change
Expand Up @@ -39,30 +39,34 @@ Fees

.. currentmodule:: starknet_py.contract

Starknet.py requires you to specify amount of Wei (for V1 transaction) or Fri (for V3 transaction) you
are willing to pay when executing either :meth:`~ContractFunction.invoke_v1` or :meth:`~ContractFunction.invoke_v3` transactions.
Starknet.py requires you to specify amount of Fri that you are willing to pay when executing :meth:`~ContractFunction.invoke_v3`.
Alternatively, you can estimate fee automatically, as described in the :ref:`automatic-fee-estimation` section below.

.. code-block:: python
await contract.functions["put"].invoke_v1(k, v, max_fee=5000)
await contract.functions["put"].invoke_v3(k, v, l1_resource_bounds=ResourceBounds(
max_amount=int(1e5), max_price_per_unit=int(1e13)
))
The ``max_fee`` argument can be also defined in :meth:`~ContractFunction.prepare_invoke_v1`. Subsequently, the :meth:`~PreparedFunctionInvokeV1.invoke` method on a prepared call can be used either with ``max_fee`` omitted or with its value overridden.
The same behavior applies to :meth:`~ContractFunction.prepare_invoke_v3` and ``l1_resource_bounds``.
The ``l1_resource_bounds`` argument can be also defined in :meth:`~ContractFunction.prepare_invoke_v3`. Subsequently, the :meth:`~PreparedFunctionInvokeV3.invoke` method on a prepared call can be used either with ``l1_resource_bounds`` omitted or with its value overridden.

.. code-block:: python
prepared_call = contract.function["put"].prepare_invoke_v1(k, v, max_fee=5000)
prepared_call = contract.function["put"].prepare_invoke_v3(k, v, l1_resource_bounds=ResourceBounds(
max_amount=int(1e5), max_price_per_unit=int(1e13)
))
await prepared_call.invoke()
# or max_fee can be overridden
await prepared_call.invoke(max_fee=10000)
# or l1_resource_bounds can be overridden
await prepared_call.invoke(l1_resource_bounds=ResourceBounds(
max_amount=int(1e5), max_price_per_unit=int(1e13)
))
.. warning::

For V1 transactions if ``max_fee`` is not specified at any step it will default to ``None``,
and will raise an exception when invoking a transaction, unless `auto_estimate` is specified and is set to `True`. The same applies to ``l1_resource_bounds`` and V3 transactions.
If ``l1_resource_bounds`` is not specified at any step it will default to ``None``,
and will raise an exception when invoking a transaction, unless `auto_estimate` is specified and is set to `True`.

Please note you will need to have enough Wei (for V1 transaction) or Fri (for V3 transaction) in your Starknet account otherwise
Please note you will need to have enough Fri in your Starknet account otherwise
transaction will be rejected.

Fee estimation
Expand All @@ -73,29 +77,27 @@ using :meth:`PreparedFunctionInvoke.estimate_fee() <starknet_py.contract.Prepare

.. code-block:: python
await contract.functions["put"].prepare_invoke_v1(k, v).estimate_fee()
await contract.functions["put"].prepare_invoke_v3(k, v).estimate_fee()
.. _automatic-fee-estimation:

Automatic fee estimation
------------------------

For testing purposes it is possible to enable automatic fee estimation when making a transaction. Starknet.py will then call :meth:`~starknet_py.net.full_node_client.FullNodeClient.estimate_fee`
internally and use the returned value, multiplied by ``1.5`` to mitigate fluctuations in price, as a ``max_fee`` for V1 transactions. For V3 transactions,
``max_amount`` will be multiplied by ``1.1``, and ``max_price_per_unit`` by ``1.5``.
internally and use the returned value. ``max_amount`` and ``max_price_per_unit`` will be multiplied by ``1.5``.

.. code-block:: python
await contract.functions["put"].invoke_v1(k, v, auto_estimate=True)
await contract.functions["put"].invoke_v3(k, v, auto_estimate=True)
.. warning::

It is strongly discouraged to use automatic fee estimation in production code as it may lead to unexpectedly high fee.

.. note::
For V1 transactions it is possible to configure the value by which the estimated fee is multiplied,
by changing ``ESTIMATED_FEE_MULTIPLIER`` in :class:`~starknet_py.net.account.account.Account`. The same applies to
``ESTIMATED_AMOUNT_MULTIPLIER`` and ``ESTIMATED_UNIT_PRICE_MULTIPLIER`` for V3 transactions.
It is possible to configure the value by which the estimated fee is multiplied,
by changing ``ESTIMATED_AMOUNT_MULTIPLIER`` and ``ESTIMATED_UNIT_PRICE_MULTIPLIER``.

Account and Client interoperability
-----------------------------------
Expand All @@ -104,7 +106,7 @@ Account and Client interoperability

:ref:`Contract` methods have been designed to be compatible with :ref:`Account` and :ref:`Client`.

:ref:`PreparedFunctionInvokeV1` and :ref:`PreparedFunctionInvokeV3` returned by :meth:`ContractFunction.prepare_invoke_v1` and :meth:`ContractFunction.prepare_invoke_v3` respectively can be used in Account methods to create Invoke transactions.
:ref:`PreparedFunctionInvokeV3` returned by :meth:`ContractFunction.prepare_invoke_v3` can be used in Account methods to create invoke transaction.

.. codesnippet:: ../../starknet_py/tests/e2e/docs/guide/test_contract_account_compatibility.py
:language: python
Expand Down
2 changes: 1 addition & 1 deletion docs/quickstart.rst
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ It supports an account contract which proxies the calls to other contracts on St
Account can be created in two ways:

* By constructor (It is required to provide an ``address`` and either ``key_pair`` or ``signer``).
* By static methods ``Account.deploy_account_v1`` or ``Account.deploy_account_v3``
* By static method ``Account.deploy_account_v3``

There are some examples how to do it:

Expand Down
1 change: 0 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -148,4 +148,3 @@ exclude = [
"**/__pycache__",
"starknet_py/tests/e2e/docs",
]

26 changes: 26 additions & 0 deletions starknet_py/contract.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
FunctionSerializationAdapterV1,
)
from starknet_py.utils.constructor_args_translator import _is_abi_v2
from starknet_py.utils.deprecation import _print_deprecation_warning
from starknet_py.utils.sync import add_sync_methods

# pylint: disable=too-many-lines
Expand Down Expand Up @@ -195,6 +196,9 @@ async def deploy_v1(
"""
Deploys a contract.
.. deprecated:: 0.25.0
This method is deprecated and will be removed in future versions. Use deploy_v3 instead.
:param deployer_address: Address of the UDC. Is set to the address of
the default UDC (same address on mainnet/sepolia) by default.
Must be set when using custom network other than ones listed above.
Expand All @@ -207,6 +211,10 @@ async def deploy_v1(
:return: DeployResult instance.
"""
# pylint: disable=too-many-arguments, too-many-locals
_print_deprecation_warning(
"deploy_v1 is deprecated and will be removed in future versions. Use deploy_v3 instead."
)

abi = self._get_abi()

return await Contract.deploy_contract_v1(
Expand Down Expand Up @@ -614,6 +622,9 @@ def prepare_invoke_v1(
:param max_fee: Max amount of Wei to be paid when executing transaction.
:return: PreparedFunctionCall.
"""
_print_deprecation_warning(
"prepare_invoke_v1 is deprecated and will be removed in future versions. Use prepare_invoke_v3 instead."
)

calldata = self._payload_transformer.serialize(*args, **kwargs)
return PreparedFunctionInvokeV1(
Expand Down Expand Up @@ -644,6 +655,10 @@ async def invoke_v1(
:param nonce: Nonce of the transaction.
:return: InvokeResult.
"""
_print_deprecation_warning(
"invoke_v1 is deprecated and will be removed in future versions. Use invoke_v3 instead."
)

prepared_invoke = self.prepare_invoke_v1(*args, **kwargs)
return await prepared_invoke.invoke(
max_fee=max_fee, nonce=nonce, auto_estimate=auto_estimate
Expand Down Expand Up @@ -835,6 +850,9 @@ async def declare_v1(
:return: DeclareResult instance.
"""

_print_deprecation_warning(
"declare_v1 is deprecated and will be removed in future versions. Use declare_v3 instead."
)
declare_tx = await account.sign_declare_v1(
compiled_contract=compiled_contract,
nonce=nonce,
Expand Down Expand Up @@ -872,6 +890,10 @@ async def declare_v2(
:return: DeclareResult instance.
"""

_print_deprecation_warning(
"declare_v2 is deprecated and will be removed in future versions. Use declare_v3 instead."
)

compiled_class_hash = _extract_compiled_class_hash(
compiled_contract_casm, compiled_class_hash
)
Expand Down Expand Up @@ -966,6 +988,10 @@ async def deploy_contract_v1(
:return: DeployResult instance.
"""
# pylint: disable=too-many-arguments, too-many-locals
_print_deprecation_warning(
"deploy_contract_v1 is deprecated and will be removed in future versions. Use deploy_contract_v3 instead."
)

deployer = Deployer(
deployer_address=deployer_address,
account_address=account.address if unique else None,
Expand Down
Loading

0 comments on commit 2478a6c

Please sign in to comment.