| 
 | 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 | +    })  | 
0 commit comments