Skip to content

Commit

Permalink
Merge branch 'development'
Browse files Browse the repository at this point in the history
  • Loading branch information
franciszekjob committed Jul 8, 2024
2 parents f8e2516 + 41877c1 commit ee0cfc9
Show file tree
Hide file tree
Showing 44 changed files with 2,016 additions and 279 deletions.
58 changes: 56 additions & 2 deletions docs/api/typed_data.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,65 @@ Parameter
:members:
:undoc-members:
:exclude-members: __init__
:member-order: bysource

-------------------
StandardParameter
-------------------


.. autoclass:: starknet_py.utils.typed_data.StandardParameter
:members:
:undoc-members:
:exclude-members: __init__
:member-order: bysource

-------------------
EnumParameter
-------------------

.. autoclass:: starknet_py.utils.typed_data.EnumParameter
:members:
:undoc-members:
:exclude-members: __init__
:member-order: bysource

-------------------
MerkleTreeParameter
-------------------

.. autoclass:: starknet_py.utils.typed_data.MerkleTreeParameter
:members:
:undoc-members:
:exclude-members: __init__
:member-order: bysource

--------------
StarkNetDomain
Domain
--------------

.. autoclass:: starknet_py.net.models.typed_data.StarkNetDomain
.. autoclass:: starknet_py.utils.typed_data.Domain
:members:
:undoc-members:
:exclude-members: __init__
:member-order: bysource

---------
BasicType
---------

.. autoclass:: starknet_py.utils.typed_data.BasicType
:members:
:undoc-members:
:exclude-members: __init__
:member-order: bysource

----------
PresetType
----------

.. autoclass:: starknet_py.utils.typed_data.PresetType
:members:
:undoc-members:
:exclude-members: __init__
:member-order: bysource
30 changes: 30 additions & 0 deletions docs/migration_guide.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,36 @@
Migration guide
===============

******************************
0.23.0 Migration guide
******************************

Version 0.23.0 of **starknet.py** comes with support for `SNIP-12 <https://github.com/starknet-io/SNIPs/blob/main/SNIPS/snip-12.md>`_!

0.23.0 Targeted versions
------------------------

- Starknet - `0.13.1.1 <https://docs.starknet.io/documentation/starknet_versions/version_notes/#version0.13.1.1>`_
- RPC - `0.7.1 <https://github.com/starkware-libs/starknet-specs/releases/tag/v0.7.1>`_

0.23.0 Breaking changes
-----------------------

.. currentmodule:: starknet_py.utils.typed_data

1. :class:`StarkNetDomain` has been renamed to :class:`Domain`
2. :class:`TypedData` field ``domain`` has been changed from ``dict`` to :class:`Domain`
3. :class:`Parameter` is now abstract - :class:`StandardParameter`, :class:`EnumParameter` and :class:`MerkleTreeParameter` should be used

0.23.0 Minor changes
-----------------------

.. currentmodule:: starknet_py.net.account.account

1. :meth:`Account.sign_message` now accepts parameter ``typed_data`` as both :class:`~starknet_py.utils.typed_data.TypedData` and :class:`~starknet_py.net.models.typed_data.TypedDataDict`
2. :meth:`Account.verify_message` now accepts parameter ``typed_data`` as both :class:`~starknet_py.utils.typed_data.TypedData` and :class:`~starknet_py.net.models.typed_data.TypedDataDict`
3. :meth:`~starknet_py.net.signer.stark_curve_signer.KeyPair.from_keystore` has been added

******************************
0.22.0 Migration guide
******************************
Expand Down
483 changes: 365 additions & 118 deletions poetry.lock

Large diffs are not rendered by default.

11 changes: 6 additions & 5 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "starknet-py"
version = "0.22.0"
version = "0.23.0"
description = "A python SDK for Starknet"
authors = ["Tomasz Rejowski <[email protected]>", "Jakub Ptak <[email protected]>"]
include = ["starknet_py", "starknet_py/utils/crypto/libcrypto_c_exports.*"]
Expand All @@ -17,17 +17,18 @@ documentation = "https://starknetpy.rtfd.io/"
python = ">=3.8, <3.13"
asgiref = "^3.4.1"
marshmallow = "^3.15.0"
marshmallow-oneofschema = "3.0.1"
marshmallow-oneofschema = "3.1.1"
typing-extensions = "^4.3.0"
marshmallow-dataclass = "<8.7.0"
marshmallow-dataclass = "<8.8.0"
poseidon-py = "0.1.4"
lark = "^1.1.5"
aiohttp = "^3.8.4"
sphinx = { version = ">=4.3.1,<8.0.0", optional = true }
enum-tools = { extras = ["sphinx"], version = "0.11.0", optional = true }
furo = { version = "^2023.5.20", optional = true }
enum-tools = { extras = ["sphinx"], version = "0.12.0", optional = true }
furo = { version = "^2024.5.6", optional = true }
pycryptodome = "^3.17"
crypto-cpp-py = "1.4.4"
eth-keyfile = "^0.8.1"

[tool.poetry.extras]
docs = ["sphinx", "enum-tools", "furo"]
Expand Down
2 changes: 1 addition & 1 deletion starknet_py/abi/v0/schemas.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from marshmallow import Schema, fields
from marshmallow_oneofschema import OneOfSchema
from marshmallow_oneofschema.one_of_schema import OneOfSchema

from starknet_py.abi.v0.shape import (
CONSTRUCTOR_ENTRY,
Expand Down
2 changes: 1 addition & 1 deletion starknet_py/abi/v1/schemas.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from marshmallow import Schema, fields
from marshmallow_oneofschema import OneOfSchema
from marshmallow_oneofschema.one_of_schema import OneOfSchema

from starknet_py.abi.v1.shape import (
ENUM_ENTRY,
Expand Down
2 changes: 1 addition & 1 deletion starknet_py/abi/v2/schemas.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from marshmallow import Schema, fields
from marshmallow_oneofschema import OneOfSchema
from marshmallow_oneofschema.one_of_schema import OneOfSchema

from starknet_py.abi.v2.shape import (
CONSTRUCTOR_ENTRY,
Expand Down
18 changes: 10 additions & 8 deletions starknet_py/contract.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ def parsed_abi(self) -> Union[AbiV0, AbiV1, AbiV2]:
return AbiParserV0(self.abi).parse()

@staticmethod
def from_abi(address: int, abi: ABI, cairo_version: int = 0) -> ContractData:
def from_abi(address: int, abi: ABI, cairo_version: int = 1) -> ContractData:
"""
Create ContractData from ABI.
Expand Down Expand Up @@ -162,7 +162,7 @@ class DeclareResult(SentTransaction):
"""

_account: BaseAccount = None # pyright: ignore
_cairo_version: int = 0
_cairo_version: int = 1

class_hash: int = None # pyright: ignore
"""Class hash of the declared contract."""
Expand Down Expand Up @@ -524,7 +524,7 @@ def __init__(
contract_data: ContractData,
client: Client,
account: Optional[BaseAccount],
cairo_version: int = 0,
cairo_version: int = 1,
*,
interface_name: Optional[str] = None,
):
Expand Down Expand Up @@ -729,7 +729,7 @@ def __init__(
abi: list,
provider: Union[BaseAccount, Client],
*,
cairo_version: int = 0,
cairo_version: int = 1,
):
"""
Should be used instead of ``from_address`` when ABI is known statically.
Expand Down Expand Up @@ -1067,10 +1067,10 @@ def compute_address(
deployer_address: int = 0,
) -> int:
"""
Computes address for given contract.
Computes address for given Cairo 0 contract.
:param salt: int
:param compiled_contract: String containing compiled contract.
:param compiled_contract: String containing compiled Cairo 0 contract.
:param constructor_args: A ``list`` or ``dict`` of arguments for the constructor.
:param deployer_address: Address of the deployer (if not provided default 0 is used).
Expand All @@ -1079,7 +1079,9 @@ def compute_address(

compiled = create_compiled_contract(compiled_contract)
assert compiled.abi is not None
translated_args = translate_constructor_args(compiled.abi, constructor_args)
translated_args = translate_constructor_args(
compiled.abi, constructor_args, cairo_version=0
)
return compute_address(
salt=salt,
class_hash=compute_class_hash(compiled),
Expand All @@ -1105,7 +1107,7 @@ def _make_functions(
contract_data: ContractData,
client: Client,
account: Optional[BaseAccount],
cairo_version: int = 0,
cairo_version: int = 1,
) -> FunctionsRepository:
repository = {}
implemented_interfaces = [
Expand Down
29 changes: 29 additions & 0 deletions starknet_py/hash/hash_method.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
from enum import Enum
from typing import List

from poseidon_py.poseidon_hash import poseidon_hash, poseidon_hash_many

from starknet_py.hash.utils import compute_hash_on_elements, pedersen_hash


class HashMethod(Enum):
"""
Enum representing hash method.
"""

PEDERSEN = "pedersen"
POSEIDON = "poseidon"

def hash(self, left: int, right: int):
if self == HashMethod.PEDERSEN:
return pedersen_hash(left, right)
if self == HashMethod.POSEIDON:
return poseidon_hash(left, right)
raise ValueError(f"Unsupported hash method: {self}.")

def hash_many(self, values: List[int]):
if self == HashMethod.PEDERSEN:
return compute_hash_on_elements(values)
if self == HashMethod.POSEIDON:
return poseidon_hash_many(values)
raise ValueError(f"Unsupported hash method: {self}.")
19 changes: 12 additions & 7 deletions starknet_py/net/account/account.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
InvokeV3,
TypeAccountTransaction,
)
from starknet_py.net.models.typed_data import TypedData
from starknet_py.net.models.typed_data import TypedDataDict
from starknet_py.net.signer import BaseSigner
from starknet_py.net.signer.stark_curve_signer import KeyPair, StarkCurveSigner
from starknet_py.serialization.data_serializers.array_serializer import ArraySerializer
Expand All @@ -49,7 +49,7 @@
)
from starknet_py.utils.iterable import ensure_iterable
from starknet_py.utils.sync import add_sync_methods
from starknet_py.utils.typed_data import TypedData as TypedDataDataclass
from starknet_py.utils.typed_data import TypedData


@add_sync_methods
Expand Down Expand Up @@ -584,13 +584,18 @@ async def execute_v3(
)
return await self._client.send_transaction(execute_transaction)

def sign_message(self, typed_data: TypedData) -> List[int]:
typed_data_dataclass = TypedDataDataclass.from_dict(typed_data)
def sign_message(self, typed_data: Union[TypedData, TypedDataDict]) -> List[int]:
if isinstance(typed_data, TypedData):
return self.signer.sign_message(typed_data, self.address)
typed_data_dataclass = TypedData.from_dict(typed_data)
return self.signer.sign_message(typed_data_dataclass, self.address)

def verify_message(self, typed_data: TypedData, signature: List[int]) -> bool:
typed_data_dataclass = TypedDataDataclass.from_dict(typed_data)
message_hash = typed_data_dataclass.message_hash(account_address=self.address)
def verify_message(
self, typed_data: Union[TypedData, TypedDataDict], signature: List[int]
) -> bool:
if not isinstance(typed_data, TypedData):
typed_data = TypedData.from_dict(typed_data)
message_hash = typed_data.message_hash(account_address=self.address)
return verify_message_signature(message_hash, signature, self.signer.public_key)

@staticmethod
Expand Down
8 changes: 5 additions & 3 deletions starknet_py/net/account/base_account.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
InvokeV3,
TypeAccountTransaction,
)
from starknet_py.net.models.typed_data import TypedData
from starknet_py.net.models.typed_data import TypedDataDict


class BaseAccount(ABC):
Expand Down Expand Up @@ -314,19 +314,21 @@ async def execute_v3(
"""

@abstractmethod
def sign_message(self, typed_data: TypedData) -> List[int]:
def sign_message(self, typed_data: TypedDataDict) -> List[int]:
"""
Sign an TypedData TypedDict for off-chain usage with the Starknet private key and return the signature.
This adds a message prefix, so it can't be interchanged with transactions.
Both v0 and v1 domain revision versions are supported.
:param typed_data: TypedData TypedDict to be signed.
:return: The signature of the TypedData TypedDict.
"""

@abstractmethod
def verify_message(self, typed_data: TypedData, signature: List[int]) -> bool:
def verify_message(self, typed_data: TypedDataDict, signature: List[int]) -> bool:
"""
Verify a signature of a TypedData dict on Starknet.
Both v0 and v1 domain revision versions are supported.
:param typed_data: TypedData TypedDict to be verified.
:param signature: signature of the TypedData TypedDict.
Expand Down
25 changes: 17 additions & 8 deletions starknet_py/net/models/typed_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,34 +2,43 @@
TypedDict structures for TypedData
"""

from typing import Any, Dict, List, TypedDict, Union
from typing import Any, Dict, List, Optional, TypedDict

from starknet_py.net.schemas.common import Revision

class Parameter(TypedDict):

class ParameterDict(TypedDict):
"""
TypedDict representing a Parameter object
"""

name: str
type: str
contains: Optional[str]


class StarkNetDomain(TypedDict):
class DomainDict(TypedDict):
"""
TypedDict representing a StarkNetDomain object
TypedDict representing a domain object (both StarkNetDomain, StarknetDomain).
"""

name: str
version: str
chainId: Union[str, int]
chainId: str
revision: Optional[Revision]


class TypedData(TypedDict):
class TypedDataDict(TypedDict):
"""
TypedDict representing a TypedData object
"""

types: Dict[str, List[Parameter]]
types: Dict[str, List[ParameterDict]]
primaryType: str
domain: StarkNetDomain
domain: DomainDict
message: Dict[str, Any]


class TypeContext(TypedDict):
parent: str
key: str
Loading

0 comments on commit ee0cfc9

Please sign in to comment.