Skip to content

Commit

Permalink
Merge branch 'development'
Browse files Browse the repository at this point in the history
  • Loading branch information
war-in committed Nov 14, 2022
2 parents 463e8ca + c830989 commit 0f5f710
Show file tree
Hide file tree
Showing 92 changed files with 15,776 additions and 31,859 deletions.
3 changes: 3 additions & 0 deletions .github/workflows/checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ jobs:
- name: Check if requirements.txt is up-to-date
run: |
poetry export -f requirements.txt --without-hashes --extras docs | cmp - requirements.txt
- name: Compile contracts
run: |
poetry run poe compile_contracts
- name: Unit & e2e test
run: |
poetry run poe test_ci
Expand Down
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -144,3 +144,9 @@ cython_debug/
*.dylib
/e2e.coverage
/unit.coverage

# Compiled contracts
/starknet_py/tests/e2e/mock/contracts_compiled/*

# Allow precompiled contracts
!/starknet_py/tests/e2e/mock/contracts_compiled/precompiled/
109 changes: 109 additions & 0 deletions docs/_ext/codesnippet.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
from typing import List, Dict, Any, Tuple

from docutils import nodes
from docutils.nodes import Element, Node
from docutils.parsers.rst import directives
from sphinx.directives import optional_int
from sphinx.directives.code import LiteralIncludeReader
from sphinx.util.docutils import SphinxDirective
from sphinx.util.typing import OptionSpec


def valid_code_snippet(code_snippet: List[str]) -> bool:
"""Check if code_snippet is non-empty"""
return len(code_snippet) > 0


class CodeSnippet(SphinxDirective):
"""
Directive class that allows multiple uses of :start-after: and :end-before: options
"""
default_start_marker = "docs: start"
default_end_marker = "docs: end"

has_content = False # No content, like a block of code, in the directive
required_arguments = 1 # Source file path is needed
optional_arguments = 0
final_argument_whitespace = True
option_spec: OptionSpec = {
"dedent": optional_int,
"language": directives.unchanged_required,
"start-after": directives.unchanged_required,
"end-before": directives.unchanged_required,
}

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.end_marker = None
self.location = None
self.filename = None
self.reader = None

def run(self) -> List[Node]:
self._set_options()
self._set_locals()
code_snippets = self._get_code_snippets()
return [self._make_node(code_snippets)]

def _get_code_snippets(self) -> List[str]:
lines = self.reader.read_file(self.filename, self.location)
result = []

while True:
code_snippet, lines = self._get_code_snippet(lines)
if not valid_code_snippet(code_snippet):
break
result.extend(code_snippet)
return result

def _get_code_snippet(self, lines: List[str]) -> Tuple[List[str], List[str]]:
"""Returns the first code snippet from lines and the rest of lines after that"""
try:
code_snippet_to_end = self.reader.end_filter(lines, self.location)
lines = lines[len(code_snippet_to_end):]
code_snippet_start_to_end = self.reader.start_filter(code_snippet_to_end, self.location)
code_snippet = self.reader.dedent_filter(code_snippet_start_to_end, self.location)
except ValueError as err:
if "pattern not found" in str(err):
return [], []
raise err
return code_snippet, lines

def _set_options(self) -> None:
self.options["start-after"] = self.options.get("start-after", self.default_start_marker)
self.options["end-before"] = self.options.get("end-after", self.default_end_marker)

def _set_locals(self) -> None:
self.end_marker = self._get_end_marker()
self.location = self._get_location()
self.filename = self._get_filename()
self.reader = LiteralIncludeReader(self.filename, self.options, self.config)

def _get_end_marker(self) -> str:
return self.options["end-before"]

def _get_location(self) -> Tuple[str, int]:
return self.state_machine.get_source_and_line(self.lineno)

def _get_filename(self) -> str:
rel_filename, filename = self.env.relfn2path(self.arguments[0])
self.env.note_dependency(rel_filename)
return filename

def _make_node(self, code_snippets) -> Node:
text = "".join(code_snippets)
node: Element = nodes.literal_block(text, text, source=self.filename)

if "language" in self.options:
node["language"] = self.options["language"]
return node


def setup(app) -> Dict[str, Any]:
app.add_directive("codesnippet", CodeSnippet)

return {
"version": "0.1",
"parallel_read_safe": True,
"parallel_write_safe": True,
}
3 changes: 1 addition & 2 deletions docs/account_creation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ Deploying an account with DeployAccount transaction requires the following:

Here is step by step example:

.. literalinclude:: ../starknet_py/tests/e2e/docs/account_creation/test_deploy_prefunded_account.py
.. codesnippet:: ../starknet_py/tests/e2e/docs/account_creation/test_deploy_prefunded_account.py
:language: python
:lines: 16-22,28-40,47-68
:dedent: 4
2 changes: 2 additions & 0 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
sys.path.insert(0, os.path.abspath("."))
sys.path.insert(0, os.path.abspath("../"))
sys.path.insert(1, os.path.dirname(os.path.abspath("../")) + os.sep + "starknet")
sys.path.append(os.path.abspath("./_ext"))

# -- Project information -----------------------------------------------------

Expand All @@ -37,6 +38,7 @@
"sphinx.ext.autosectionlabel",
"sphinx_rtd_theme",
"enum_tools.autoenum",
"codesnippet",
]

# Add any paths that contain templates here, relative to this directory.
Expand Down
2 changes: 1 addition & 1 deletion docs/contract.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Contract
.. py:module:: starknet_py.contract
.. autoclass:: Contract
:members: from_address, __init__, functions, deploy, from_address_sync, deploy_sync, compute_address, compute_contract_hash, ProxyConfig
:members: from_address, __init__, functions, deploy, from_address_sync, deploy_sync, compute_address, compute_contract_hash

.. autoclass:: ContractFunction
:exclude-members: __init__, __new__
Expand Down
3 changes: 3 additions & 0 deletions docs/development.rst
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ Setup
# Install dependencies
poetry install
# Compile contracts
poe compile_contracts
# Make sure everything was installed properly
poe test
Expand Down
57 changes: 34 additions & 23 deletions docs/guide.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,37 @@ Let's say we have a contract with this interface:

.. literalinclude:: ../starknet_py/tests/e2e/docs/guide/test_using_existing_contracts.py
:language: python
:lines: 6-24
:start-after: docs-abi: start
:end-before: docs-abi: end


This is how we can interact with it:

.. literalinclude:: ../starknet_py/tests/e2e/docs/guide/test_using_existing_contracts.py
.. codesnippet:: ../starknet_py/tests/e2e/docs/guide/test_using_existing_contracts.py
:language: python
:dedent: 4


Resolving proxies
-----------------

Resolving proxies is a powerful feature of Starknet.py. If your contract is a proxy to some implementation, you can use
high-level :meth:`Contract.from_address` method to get a contract instance.

:meth:`Contract.from_address` works with contracts which are not proxies, so it is the most universal method of getting
a contract not knowing the abi.

Check out the code!

.. codesnippet:: ../starknet_py/tests/e2e/docs/guide/test_resolving_proxies.py
:language: python
:lines: 34-40,44-49,57-66,70-74,78-82,86-101
:dedent: 4

.. note::

Although :meth:`Contract.from_address()` works like a charm it must perform some calls to get an abi of the contract.
If you know the abi statically just use the :ref:`Contract` constructor. It will save some time!


AccountClient details
---------------------
Expand All @@ -30,9 +51,8 @@ just prepare calls through contract interface and send it with AccountClient.exe

Here is an example:

.. literalinclude:: ../starknet_py/tests/e2e/docs/guide/test_account_client_details.py
.. codesnippet:: ../starknet_py/tests/e2e/docs/guide/test_account_client_details.py
:language: python
:lines: 8-13,17-21,26-56
:dedent: 4


Expand All @@ -44,9 +64,8 @@ By default, :ref:`Account Client` uses signing method of OpenZeppelin's account
signing algorithm, it is possible to create ``AccountClient`` with custom
:ref:`Signer` implementation.

.. literalinclude:: ../starknet_py/tests/e2e/docs/guide/test_custom_signer.py
.. codesnippet:: ../starknet_py/tests/e2e/docs/guide/test_custom_signer.py
:language: python
:lines: 11-41
:dedent: 4


Expand All @@ -56,9 +75,8 @@ Signing off-chain messages
:ref:`Account Client` lets you sign an off-chain message by using encoding standard proposed `here <https://github.com/argentlabs/argent-x/discussions/14>`_.
You can also **verify a message**, which is done by a call to ``is_valid_signature`` endpoint in the account's contract (e.g. `OpenZeppelin's account contract <https://github.com/starkware-libs/cairo-lang/blob/4e233516f52477ad158bc81a86ec2760471c1b65/src/starkware/starknet/third_party/open_zeppelin/Account.cairo#L115>`_).

.. literalinclude:: ../starknet_py/tests/e2e/docs/guide/test_sign_offchain_message.py
.. codesnippet:: ../starknet_py/tests/e2e/docs/guide/test_sign_offchain_message.py
:language: python
:lines: 9-44,51-59,66-76
:dedent: 4


Expand All @@ -71,9 +89,8 @@ Since Cairo 0.10.0 Declare transactions can be signed and in the future, declari

Here's an example how to use it.

.. literalinclude:: ../starknet_py/tests/e2e/docs/guide/test_declaring_contracts.py
.. codesnippet:: ../starknet_py/tests/e2e/docs/guide/test_declaring_contracts.py
:language: python
:lines: 10-20
:dedent: 4

.. note::
Expand All @@ -86,9 +103,8 @@ Deploying new contracts

Here's how you can deploy new contracts:

.. literalinclude:: ../starknet_py/tests/e2e/docs/guide/test_deploying_new_contracts.py
.. codesnippet:: ../starknet_py/tests/e2e/docs/guide/test_deploying_new_contracts.py
:language: python
:lines: 10-33,37-47,51-57,61-72
:dedent: 4


Expand Down Expand Up @@ -150,9 +166,8 @@ Handling client errors
-----------------------
You can use :class:`starknet_py.net.client_errors.ClientError` to catch errors from invalid requests:

.. literalinclude:: ../starknet_py/tests/e2e/docs/guide/test_handling_client_errors.py
.. codesnippet:: ../starknet_py/tests/e2e/docs/guide/test_handling_client_errors.py
:language: python
:lines: 8-15,19-21
:dedent: 4


Expand Down Expand Up @@ -230,9 +245,8 @@ Using CairoSerializer
CairoSerializer can be used to transform any data (like a function call or an event) between cairo and python format. It requires an abi of the contract, types of values and data to be serialized.
Here is a usage example:

.. literalinclude:: ../starknet_py/tests/e2e/docs/guide/test_using_cairo_serializer.py
.. codesnippet:: ../starknet_py/tests/e2e/docs/guide/test_using_cairo_serializer.py
:language: python
:lines: 9-39,44-49,54-97
:dedent: 4


Expand Down Expand Up @@ -260,9 +274,8 @@ Using own full node allows for querying StarkNet with better performance.
Since gateway will be deprecated at some point in the future, having ``FullNodeClient`` with interface uniform with that of ``GatewayClient``
will allow for simple migration for StarkNet.py users.

.. literalinclude:: ../starknet_py/tests/e2e/docs/guide/test_full_node_client.py
.. codesnippet:: ../starknet_py/tests/e2e/docs/guide/test_full_node_client.py
:language: python
:lines: 12-15,24-25
:dedent: 4


Expand All @@ -285,9 +298,8 @@ The message's count is an `int`, representing the number of unconsumed messages
Since the `nonce`'s value will always be unique for each message, this value is either 0 or 1
(0 meaning the message is consumed or not received yet, and 1 for unconsumed, queued message).

.. literalinclude:: ../starknet_py/tests/e2e/docs/guide/test_eth_sn_messages.py
.. codesnippet:: ../starknet_py/tests/e2e/docs/guide/test_eth_sn_messages.py
:language: python
:lines: 12-42,49-49,63-75
:dedent: 4


Expand All @@ -297,7 +309,6 @@ StarkNet -> Ethereum messages
As in previous section, you can provide L1 message content, and then fetch the queued message count.
The return value is an `int`, representing the number of unconsumed messages on L1 of that exact content.

.. literalinclude:: ../starknet_py/tests/e2e/docs/guide/test_sn_eth_messages.py
.. codesnippet:: ../starknet_py/tests/e2e/docs/guide/test_sn_eth_messages.py
:language: python
:lines: 11-38,44-45,59-65,71-76
:dedent: 4
27 changes: 23 additions & 4 deletions docs/migration_guide.rst
Original file line number Diff line number Diff line change
@@ -1,3 +1,24 @@
0.9.0 Migration guide
=====================

Starknet.py 0.9.0 brings support for `RPC 0.2.0 <https://github.com/starkware-libs/starknet-specs/releases/tag/v0.2.0>`_,
updates :meth:`Contract.from_address` method to work with the newest proxies and removes some deprecated features.

Breaking Changes
----------------

- Removed deprecated `Account.sign_transaction`. Use new `Account.sign_invoke_transaction`.
- Removed deprecated `InvokeFunction` as `call_contract` parameter. Use `Call` class instead.
- `StateDiff` has `declared_contract_hashes` instead of `declared_contracts` field (only name has changed).
- Support for RPC 0.1.0 has been dropped in favour of RPC 0.2.0.


Contract.from_address
---------------------

Check out the Guide with the new section :ref:`Resolving proxies` to see how to easily use proxies with the Starknet.py.


0.8.0 Migration guide
=====================

Expand All @@ -13,8 +34,8 @@ using new flow:

or support deploying through syscall or `Universal Deployer Contract <https://community.starknet.io/t/universal-deployer-contract-proposal/1864>`_.

Breaking Changes
----------------
0.8.0 Breaking Changes
----------------------

- `entry_point_selector` has been removed from `v1` transactions. `InvokeTransaction`'s field has been changed to `Optional[int]`
- `net.models.address.compute_address` signature has been changed and use of keyword arguments is now mandatory
Expand Down Expand Up @@ -52,8 +73,6 @@ removed in the future.
New Cairo syntax
^^^^^^^^^^^^^^^^^^^^^^^

.. TODO: Change the new syntax link with a better one once StarkWare releases it.
With the update of `cairo-lang <https://github.com/starkware-libs/cairo-lang>`_ to version ``0.10.0``,
the syntax of contracts written in cairo changes significantly.
You can see the new syntax `here <https://starkware.notion.site/starkware/StarkNet-0-10-0-4ac978234c384a30a195ce4070461257#8bfeb76259234f32b5f42376f0d976b9>`_.
Expand Down
Loading

0 comments on commit 0f5f710

Please sign in to comment.