Skip to content

Commit 0391b35

Browse files
committed
clean up finished
1 parent 9abacbe commit 0391b35

File tree

6 files changed

+158
-147
lines changed

6 files changed

+158
-147
lines changed

.pylintrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -561,7 +561,7 @@ max-locals=15
561561
max-parents=7
562562

563563
# Maximum number of public methods for a class (see R0904).
564-
max-public-methods=20
564+
max-public-methods=23
565565

566566
# Maximum number of return / yield for function / method body.
567567
max-returns=6

starknet_py/hash/outside_execution.py

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
from starknet_py.net.client_models import OutsideExecution
2+
3+
from starknet_py.constants import SNIP9InterfaceVersion
4+
5+
from starknet_py.net.schemas.common import Revision
6+
from starknet_py.utils import typed_data as td
7+
8+
SNIP9_INTERFACE_ID_TO_SNIP12_REVISION = {
9+
SNIP9InterfaceVersion.V1: Revision.V0,
10+
SNIP9InterfaceVersion.V2: Revision.V1,
11+
}
12+
13+
def outside_execution_to_typed_data(
14+
outside_execution: OutsideExecution,
15+
snip9_version: SNIP9InterfaceVersion,
16+
chain_id: int
17+
) -> td.TypedData:
18+
"""
19+
SNIP-12 Typed Data for OutsideExecution implementation. For revision V0 and V1.
20+
"""
21+
22+
revision = SNIP9_INTERFACE_ID_TO_SNIP12_REVISION[snip9_version]
23+
24+
if revision == Revision.V0:
25+
return td.TypedData.from_dict({
26+
'types': {
27+
'StarkNetDomain': [
28+
{'name': 'name', 'type': 'felt'},
29+
{'name': 'version', 'type': 'felt'},
30+
{'name': 'chainId', 'type': 'felt'},
31+
],
32+
'OutsideExecution': [
33+
{'name': 'caller', 'type': 'felt' },
34+
{'name': 'nonce', 'type': 'felt' },
35+
{'name': 'execute_after', 'type': 'felt' },
36+
{'name': 'execute_before', 'type': 'felt' },
37+
{'name': 'calls_len', 'type': 'felt' },
38+
{'name': 'calls', 'type': 'OutsideCall*' },
39+
],
40+
'OutsideCall': [
41+
{ 'name': 'to', 'type': 'felt' },
42+
{ 'name': 'selector', 'type': 'felt' },
43+
{ 'name': 'calldata_len', 'type': 'felt' },
44+
{ 'name': 'calldata', 'type': 'felt*' },
45+
],
46+
},
47+
'primaryType': 'OutsideExecution',
48+
'domain': {
49+
'name': 'Account.execute_from_outside',
50+
'version': '1',
51+
'chainId': str(chain_id),
52+
'revision': Revision.V0,
53+
},
54+
'message': {
55+
'caller': outside_execution.caller,
56+
'nonce': outside_execution.nonce,
57+
'execute_after': outside_execution.execute_after,
58+
'execute_before': outside_execution.execute_before,
59+
'calls_len': len(outside_execution.calls),
60+
'calls': [
61+
{
62+
'to': call.to_addr,
63+
'selector': call.selector,
64+
'calldata_len': len(call.calldata),
65+
'calldata': call.calldata,
66+
} for call in outside_execution.calls
67+
],
68+
},
69+
})
70+
71+
# revision == Revision.V1
72+
return td.TypedData.from_dict({
73+
'types': {
74+
'StarknetDomain': [
75+
{'name': 'name', 'type': 'shortstring'},
76+
{'name': 'version', 'type': 'shortstring'},
77+
{'name': 'chainId', 'type': 'shortstring'},
78+
{'name': 'revision', 'type': 'shortstring'},
79+
],
80+
'OutsideExecution': [
81+
{'name': 'Caller', 'type': 'ContractAddress' },
82+
{'name': 'Nonce', 'type': 'felt' },
83+
{'name': 'Execute After', 'type': 'u128' },
84+
{'name': 'Execute Before', 'type': 'u128' },
85+
{'name': 'Calls', 'type': 'Call*' },
86+
],
87+
'Call': [
88+
{ 'name': 'To', 'type': 'ContractAddress' },
89+
{ 'name': 'Selector', 'type': 'selector' },
90+
{ 'name': 'Calldata', 'type': 'felt*' },
91+
],
92+
},
93+
'primaryType': 'OutsideExecution',
94+
'domain': {
95+
'name': 'Account.execute_from_outside',
96+
'version': '2',
97+
'chainId': str(chain_id),
98+
'revision': Revision.V1,
99+
},
100+
'message': {
101+
'Caller': outside_execution.caller,
102+
'Nonce': outside_execution.nonce,
103+
'Execute After': outside_execution.execute_after,
104+
'Execute Before': outside_execution.execute_before,
105+
'Calls': [
106+
{
107+
'To': call.to_addr,
108+
'Selector': call.selector,
109+
'Calldata': call.calldata,
110+
} for call in outside_execution.calls
111+
],
112+
},
113+
})

starknet_py/net/account/account.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@
88
from starknet_py.hash.address import compute_address
99
from starknet_py.hash.selector import get_selector_from_name
1010
from starknet_py.hash.utils import verify_message_signature
11+
from starknet_py.hash.outside_execution import outside_execution_to_typed_data
1112
from starknet_py.net.account.account_deployment_result import AccountDeploymentResult
12-
from starknet_py.net.account.base_account import BaseAccount
13+
from starknet_py.net.account.base_account import BaseAccount, SNIP9SupportMixin
1314
from starknet_py.net.client import Client
14-
from starknet_py.contract import Contract
1515
from starknet_py.constants import SNIP9InterfaceVersion
1616
from starknet_py.net.client_models import (
1717
Call,
@@ -54,8 +54,9 @@
5454
from starknet_py.utils.sync import add_sync_methods
5555
from starknet_py.utils.typed_data import TypedData
5656

57+
5758
@add_sync_methods
58-
class Account(BaseAccount):
59+
class Account(BaseAccount, SNIP9SupportMixin):
5960
"""
6061
Default Account implementation.
6162
"""
@@ -415,7 +416,9 @@ async def sign_outside_execution_call(
415416
)
416417
chain_id = await self._get_chain_id()
417418
signature = self.signer.sign_message(
418-
outside_execution.get_typed_data(version, chain_id),
419+
outside_execution_to_typed_data(
420+
outside_execution, version, chain_id
421+
),
419422
self.address
420423
)
421424
selector_for_version = {

starknet_py/net/account/base_account.py

Lines changed: 34 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,40 @@
2727
)
2828
from starknet_py.net.models.typed_data import TypedDataDict
2929

30+
class SNIP9SupportMixin(ABC):
31+
32+
@abstractmethod
33+
async def get_snip9_nonce(self) -> int:
34+
"""
35+
Generate special valid nonce (passed check_snip9_nonce) for external calls execution.
36+
"""
37+
38+
@abstractmethod
39+
async def supports_interface(self, interface_id: SNIP9InterfaceVersion) -> bool:
40+
"""
41+
Check if the account supports the given SNIP9 interface. Part of ISRC5 standard.
42+
"""
43+
44+
@abstractmethod
45+
async def sign_outside_execution_call(
46+
self,
47+
calls: Calls,
48+
execution_time_bounds: ExecutionTimeBounds,
49+
*,
50+
caller: AddressRepresentation = ANY_CALLER,
51+
nonce: Optional[int] = None,
52+
version: Optional[SNIP9InterfaceVersion] = None,
53+
) -> Call:
54+
"""
55+
Creates a call for an external execution (SNIP-9 specification).
56+
57+
:param calls: Single call or list of calls to be executed by outside caller.
58+
:param execution_time_bounds: Execution time bounds for the call.
59+
:param caller: Address of the caller. IMPORTANT! By default it is ANY_CALLER.
60+
:param nonce: Nonce for the transaction. Is populated automatically if not provided.
61+
:param version: SNIP-9 interface version. Method will check which version account
62+
supports and use the highest one and populate the value.
63+
"""
3064

3165
class BaseAccount(ABC):
3266
"""
@@ -92,18 +126,6 @@ async def get_nonce(
92126
:return: nonce of the account.
93127
"""
94128

95-
@abstractmethod
96-
async def get_snip9_nonce(self) -> int:
97-
"""
98-
Generate special valid nonce (passed check_snip9_nonce) for external calls execution.
99-
"""
100-
101-
@abstractmethod
102-
async def supports_interface(self, interface_id: SNIP9InterfaceVersion) -> bool:
103-
"""
104-
Check if the account supports the given SNIP9 interface. Part of ISRC5 standard.
105-
"""
106-
107129
@abstractmethod
108130
async def get_balance(
109131
self,
@@ -173,27 +195,6 @@ async def sign_invoke_v3(
173195
:return: Invoke created from the calls.
174196
"""
175197

176-
@abstractmethod
177-
async def sign_outside_execution_call(
178-
self,
179-
calls: Calls,
180-
execution_time_bounds: ExecutionTimeBounds,
181-
*,
182-
caller: AddressRepresentation = ANY_CALLER,
183-
nonce: Optional[int] = None,
184-
version: Optional[SNIP9InterfaceVersion] = None,
185-
) -> Call:
186-
"""
187-
Creates a call for an external execution (SNIP-9 specification).
188-
189-
:param calls: Single call or list of calls to be executed by outside caller.
190-
:param execution_time_bounds: Execution time bounds for the call.
191-
:param caller: Address of the caller. IMPORTANT! By default it is ANY_CALLER.
192-
:param nonce: Nonce for the transaction. Is populated automatically if not provided.
193-
:param version: SNIP-9 interface version. Method will check which version account
194-
supports and use the highest one and populate the value.
195-
"""
196-
197198
# pylint: disable=line-too-long
198199
@abstractmethod
199200
async def sign_declare_v1(

starknet_py/net/client_models.py

Lines changed: 0 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -28,22 +28,12 @@
2828
from starknet_py.abi.v2.shape import AbiDictEntry as AbiDictEntryV2
2929
from starknet_py.abi.v2.shape import AbiDictList as AbiDictListV2
3030

31-
from starknet_py.constants import SNIP9InterfaceVersion
32-
33-
from starknet_py.utils import typed_data as td
3431
from starknet_py.utils.constructor_args_translator import _is_abi_v2
3532

36-
from starknet_py.net.schemas.common import Revision
3733

3834
# pylint: disable=too-many-lines
3935

4036

41-
SNIP9_INTERFACE_ID_TO_SNIP12_REVISION = {
42-
SNIP9InterfaceVersion.V1: Revision.V0,
43-
SNIP9InterfaceVersion.V2: Revision.V1,
44-
}
45-
46-
4737
Hash = Union[int, str]
4838
Tag = Literal["pending", "latest"]
4939

@@ -1167,101 +1157,3 @@ def to_abi_dict(self) -> Dict:
11671157
"calldata": call.calldata
11681158
} for call in self.calls]
11691159
}
1170-
1171-
def get_typed_data(self, snip9_version: SNIP9InterfaceVersion, chain_id: int) -> td.TypedData:
1172-
"""
1173-
SNIP-12 Typed Data for OutsideExecution implementation. For revision V0 and V1.
1174-
"""
1175-
1176-
revision = SNIP9_INTERFACE_ID_TO_SNIP12_REVISION[snip9_version]
1177-
1178-
if revision == Revision.V0:
1179-
return td.TypedData.from_dict({
1180-
'types': {
1181-
'StarkNetDomain': [
1182-
{'name': 'name', 'type': 'felt'},
1183-
{'name': 'version', 'type': 'felt'},
1184-
{'name': 'chainId', 'type': 'felt'},
1185-
],
1186-
'OutsideExecution': [
1187-
{'name': 'caller', 'type': 'felt' },
1188-
{'name': 'nonce', 'type': 'felt' },
1189-
{'name': 'execute_after', 'type': 'felt' },
1190-
{'name': 'execute_before', 'type': 'felt' },
1191-
{'name': 'calls_len', 'type': 'felt' },
1192-
{'name': 'calls', 'type': 'OutsideCall*' },
1193-
],
1194-
'OutsideCall': [
1195-
{ 'name': 'to', 'type': 'felt' },
1196-
{ 'name': 'selector', 'type': 'felt' },
1197-
{ 'name': 'calldata_len', 'type': 'felt' },
1198-
{ 'name': 'calldata', 'type': 'felt*' },
1199-
],
1200-
},
1201-
'primaryType': 'OutsideExecution',
1202-
'domain': {
1203-
'name': 'Account.execute_from_outside',
1204-
'version': '1',
1205-
'chainId': str(chain_id),
1206-
'revision': Revision.V0,
1207-
},
1208-
'message': {
1209-
'caller': self.caller,
1210-
'nonce': self.nonce,
1211-
'execute_after': self.execute_after,
1212-
'execute_before': self.execute_before,
1213-
'calls_len': len(self.calls),
1214-
'calls': [
1215-
{
1216-
'to': call.to_addr,
1217-
'selector': call.selector,
1218-
'calldata_len': len(call.calldata),
1219-
'calldata': call.calldata,
1220-
} for call in self.calls
1221-
],
1222-
},
1223-
})
1224-
1225-
# revision == Revision.V1
1226-
return td.TypedData.from_dict({
1227-
'types': {
1228-
'StarknetDomain': [
1229-
{'name': 'name', 'type': 'shortstring'},
1230-
{'name': 'version', 'type': 'shortstring'},
1231-
{'name': 'chainId', 'type': 'shortstring'},
1232-
{'name': 'revision', 'type': 'shortstring'},
1233-
],
1234-
'OutsideExecution': [
1235-
{'name': 'Caller', 'type': 'ContractAddress' },
1236-
{'name': 'Nonce', 'type': 'felt' },
1237-
{'name': 'Execute After', 'type': 'u128' },
1238-
{'name': 'Execute Before', 'type': 'u128' },
1239-
{'name': 'Calls', 'type': 'Call*' },
1240-
],
1241-
'Call': [
1242-
{ 'name': 'To', 'type': 'ContractAddress' },
1243-
{ 'name': 'Selector', 'type': 'selector' },
1244-
{ 'name': 'Calldata', 'type': 'felt*' },
1245-
],
1246-
},
1247-
'primaryType': 'OutsideExecution',
1248-
'domain': {
1249-
'name': 'Account.execute_from_outside',
1250-
'version': '2',
1251-
'chainId': str(chain_id),
1252-
'revision': Revision.V1,
1253-
},
1254-
'message': {
1255-
'Caller': self.caller,
1256-
'Nonce': self.nonce,
1257-
'Execute After': self.execute_after,
1258-
'Execute Before': self.execute_before,
1259-
'Calls': [
1260-
{
1261-
'To': call.to_addr,
1262-
'Selector': call.selector,
1263-
'Calldata': call.calldata,
1264-
} for call in self.calls
1265-
],
1266-
},
1267-
})

starknet_py/tests/unit/net/models/transaction_test.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import datetime
22

3+
from starknet_py.hash.outside_execution import outside_execution_to_typed_data
34
from starknet_py.net.client_models import OutsideExecution, Call
45
from starknet_py.net.models import StarknetChainId
56

@@ -25,7 +26,8 @@ def test_generate_message_hash_for_execute_outside_transaction():
2526
]
2627
)
2728

28-
message_hash = execution.get_typed_data(
29+
message_hash = outside_execution_to_typed_data(
30+
execution,
2931
SNIP9InterfaceVersion.V1,
3032
StarknetChainId.SEPOLIA
3133
).message_hash(0x00000000001)

0 commit comments

Comments
 (0)