
    (i61                         d dl Z d dlZd dlZd dlZd dlmZmZ d dlmZm	Z	m
Z
 d dlmZ d dlZd dlmZmZmZmZ  G d de      Z G d d	ee
      Z G d de
      Zy)    N)OrderedDictdefaultdict)ListTuple
NamedTuple)keccak)Array
EIP712Typefrom_solidity_typeBytesJSONEncoderc                        e Zd ZdZed        Zy)OrderedAttributesMetaz=Metaclass to ensure struct attribute order is preserved.
    c                     t               S N)r   )mcsnamebasess      K/var/www/br/venv/lib/python3.12/site-packages/poly_eip712_structs/struct.py__prepare__z!OrderedAttributesMeta.__prepare__   s
    }    N)__name__
__module____qualname____doc__classmethodr    r   r   r   r      s     r   r   c                   p    e Zd ZdZ fdZe fd       ZddZd Zd Z	d Z
eded	efd
       Zed        Zed        Zed	efd       Zd	efdZed	eeeef      fd       Zed        Zddd d	efdZddd d	efdZddd d	efdZeded	dfd       Zed        Zed        Zd Z d Z!d Z"d Z#d Z$ xZ%S ) EIP712Structa  A representation of an EIP712 struct. Subclass it to use it.

    Example:
        from eip712_structs import EIP712Struct, String

        class MyStruct(EIP712Struct):
            some_param = String()

        struct_instance = MyStruct(some_param='some_value')
    c                    t         t        |   | j                  d        | j	                         }t               | _        |D ]=  \  }}|j                  |      }t        |t
              r |di |}|| j                  |<   ? y Nr   )	superr   __init__	type_nameget_membersdictvaluesget
isinstance)selfkwargsmembersr   typvalue	__class__s         r   r"   zEIP712Struct.__init__!   ss    lD*4>>4@""$f  	&ID#JJt$E%&e %DKK		&r   c                 F    t        |   di | | j                  | _        y r    )r!   __init_subclass__r   r#   )clsr*   r.   s     r   r0   zEIP712Struct.__init_subclass__+   s    !+F+r   c                 d   t               }| j                         D ]  \  }}t        |t              rAt	        |t
              r1| j                  |      }|j                  |j                                W|j                  |j                  | j                  |                 dj                  |      S )zReturns the struct's encoded value.

        A struct's encoded value is a concatenation of the bytes32 representation of each member of the struct.
        Order is preserved.

        :param value: This parameter is not used for structs.
        r   )listr$   r(   type
issubclassr   get_data_valueappendhash_structencode_valuer&   join)r)   r-   encoded_valuesr   r,   
sub_structs         r   r9   zEIP712Struct.encode_value0   s     ))+ 	KID##t$C)F!006
%%j&<&<&>? %%c&6&6t{{47H&IJ	K xx''r   c                 8    | j                   j                  |      S )z5Get the value of the given struct parameter.
        )r&   r'   )r)   r   s     r   r6   zEIP712Struct.get_data_valueC   s     {{t$$r   c                 @    || j                   v r|| j                   |<   yy)z5Set the value of the given struct parameter.
        N)r&   )r)   r   r-   s      r   set_data_valuezEIP712Struct.set_data_valueH   s#     4;; %DKK r   c                     t               }| j                  j                         D ].  \  }}t        |t              r|j                         ||<   *|||<   0 |S )zProvide the entire data dictionary representing the struct.

        Nested structs instances are also converted to dict form.
        )r%   r&   itemsr(   r   	data_dict)r)   resultkvs       r   rB   zEIP712Struct.data_dictN   sT    
 KK%%' 	DAq!\*KKMq	q			
 r   resolve_referencesreturnc                 j     j                         D cg c]  \  }}|j                   d|  }}} j                   ddj                  |       d}|rWt               } j	                  |       t        t         fd|D              d       }|D ]  }||j                  d	      z  } |S c c}}w )
N (,)c              3   .   K   | ]  }|k7  s	|  y wr   r   ).0sr1   s     r   	<genexpr>z,EIP712Struct._encode_type.<locals>.<genexpr>c   s     (Rqc(Rs   
c                     | j                   S r   )r#   )rO   s    r   <lambda>z+EIP712Struct._encode_type.<locals>.<lambda>c   s    bcbmbm r   )keyF)rF   )r$   r#   r:   set_gather_reference_structssortedr3   _encode_type)	r1   rF   r   r,   member_sigs
struct_sigreference_structssorted_structsstructs	   `        r   rW   zEIP712Struct._encode_type[   s    BE//BSTYT3#--$0TTa(='>a@
 #))*;<#D(R4E(R$RXmnN( Lf11U1KK
L Us   B/c                     | j                         D cg c]/  }t        |d   t              st        |d   t              s+|d   1 }}|D ])  }||vs|j                  |       |j                  |       + yc c}w )zbFinds reference structs defined in this struct type, and inserts them into the given set.
           N)r$   r(   r4   r5   r   addrU   )r1   
struct_setmstructsr\   s        r   rU   z&EIP712Struct._gather_reference_structsh   sx     "%!2pAj1t6LQ[\]^_\`bnQo1Q4pp 	=FZ'v&00<	= qs   A8A8 A8c                 $    | j                  d      S )zGet the encoded type signature of the struct.

        Nested structs are also encoded, and appended in alphabetical order.
        T)rW   r1   s    r   encode_typezEIP712Struct.encode_typer   s     %%r   c                 6    t        | j                               S )z1Get the keccak hash of the struct's encoded type.)text)r   re   rd   s    r   	type_hashzEIP712Struct.type_hashz   s     3??,--r   c                 r    t        dj                  | j                         | j                         g            S )zYThe hash of the struct.

        hash_struct => keccak(type_hash || encode_data)
        r   )r   r:   rh   r9   )r)   s    r   r8   zEIP712Struct.hash_struct   s-    
 chh 0$2C2C2EFGHHr   c                     | j                   j                         D cg c]=  }t        |d   t              s&t        |d   t              rt        |d   t              r|? }}|S c c}w )zA list of tuples of supported parameters.

        Each tuple is (<parameter_name>, <parameter_type>). The list's order is determined by definition order.
        r^   )__dict__rA   r(   r
   r4   r5   r   )r1   ra   r+   s      r   r$   zEIP712Struct.get_members   sc     "ll002 Sj1z6R!!A$-*QqT<2P  S SSs   AA#c                 H    | xs t         j                  }|st        d      |S )NzFDomain must be provided, or eip712_structs.default_domain must be set.)poly_eip712_structsdefault_domain
ValueError)domainrC   s     r   _assert_domainzEIP712Struct._assert_domain   s'    =.==effr   rp   c                 V   | j                  |      }|| h}| j                  |       t               }|D ]A  }|j                         D cg c]  }|d   |d   j                  d }}|||j                  <   C | j                  ||j                         | j                         d}|S c c}w )a  Convert a struct into a dictionary suitable for messaging.

            Dictionary is of the form:
                {
                    'primaryType': Name of the primary type,
                    'types': Definition of each included struct type (including the domain type)
                    'domain': Values for the domain struct,
                    'message': Values for the message struct,
                }

            :returns: This struct + the domain in dict form, structured as specified for EIP712 messages.
            r   r^   )r   r4   )primaryTypetypesrp   message)rq   rU   r%   r$   r#   rB   )r)   rp   rb   rt   r\   ra   members_jsonrC   s           r   
to_messagezEIP712Struct.to_message   s     $$V,4.&&w/  	3F ))+-  !! -L - '3E&""#	3  >>&&(~~'	
 -s   B&c                 Z    | j                  |      }t        j                  |t              S )Nrd   )rw   jsondumpsr   )r)   rp   ru   s      r   to_message_jsonzEIP712Struct.to_message_json   s"    //&)zz''788r   c                 p    | j                  |      }d|j                         z   | j                         z   }|S )a^  Return a ``bytes`` object suitable for signing, as specified for EIP712.

        As per the spec, bytes are constructed as follows:
            ``b'' + domain_hash_bytes + struct_hash_bytes``

        :param domain: The domain to include in the hash bytes. If None, uses ``eip712_structs.default_domain``
        :return: The bytes object
        s   )rq   r8   )r)   rp   rC   s      r   signable_byteszEIP712Struct.signable_bytes   s:     $$V,v1133d6F6F6HHr   message_dictStructTuplec           
         t               }t        t              }|d   D ]b  }t        |t        fi       }|d   |   D ]>  }|d   }t        |d         }t        |||       |&||   j                  ||d   f       @ |||<   d |j                         D ]  \  }	}
d}||	   }|
D ]|  \  }}t        j                  ||      }|j                  d      }||   }|j                  d      r-|j                  d      xs d}t        ||t        ||             pt        |||       ~  ||d	      }|d
   } |di |d   } |di |d   }t        ||      }|S )aL  Convert a message dictionary into two EIP712Struct objects - one for domain, another for the message struct.

        Returned as a StructTuple, which has the attributes ``message`` and ``domain``.

        Example:
            my_msg = { .. }
            deserialized = EIP712Struct.from_message(my_msg)
            msg_struct = deserialized.message
            domain_struct = deserialized.domain

        :param message_dict: The dictionary, such as what is produced by EIP712Struct.to_message.
        :return: A StructTuple object, containing the message and domain structs.
        rt   r   r4   z([a-zA-Z0-9_]+)(\[(\d+)?\])?r^         r   rs   EIP712Domainru   rp   )ru   rp   r   )r%   r   r3   r4   r   r   setattrr7   rA   rematchgroupr	   r   )r1   r~   rb   unfulfilled_struct_paramsr#   StructFromJSONmembermember_namemember_sol_typestruct_nameunfulfilled_member_namesregex_patternstruct_classr   r   base_type_name
ref_structarr_lenprimary_structdomain_structprimary_resultdomain_resultrC   s                          r   from_messagezEIP712Struct.from_message   s    &$/$5!%g. 	0I!)l_bAN&w/	: _$Vn"4VF^"D_E"*-i8??fU[n@]^_ "0GI	0  6O5T5T5V 	<1K1;M";/L#; 	<i	:!&Q$^4
;;q>#kk!n1GL$j'0JKL$
;	<		< !m!<=/'B,y*AB%?X(>?^MJr   c                 t    | j                         D ch c]  }|d   	 }}||vrt        d| d      y c c}w )Nr   "z!" is not defined for this struct.)r$   KeyError)r1   rS   tupmember_namess       r   _assert_key_is_memberz"EIP712Struct._assert_key_is_member  sG    *-//*;<3A<<l"Qse#DEFF # =s   5c                    t        | j                               }||   }t        |t              r^t	        |t
              rNt        |t
              r#|j                  d      |j                  d      k7  rt        dt        |       d|       y	 |j                  |       y# t        $ r!}t        dt        |       d| d      |d}~ww xY w)z'Eagerly check for a correct member typeFzGiven value is of type z, but we expected zThe python type z/ does not appear to be supported for data type .N)
r%   r$   r(   r4   r5   r   rW   ro   r9   	Exception)r1   rS   r-   r+   r,   es         r   _assert_property_typez"EIP712Struct._assert_property_type  s     s()clc4 Z\%Be\2e6H6H6OSVScScdiSj6j #:4;-GYZ]Y^!_`` 7kQ  ' Q #3DK= ABBEa"I JOPQQs   B   	C
)CC
c                 Z    | j                  |       | j                  j                  |      S z:Provide access directly to the underlying value dictionary)r   r&   __getitem__)r)   rS   s     r   r   zEIP712Struct.__getitem__  s%    ""3'{{&&s++r   c                     | j                  |       | j                  ||       | j                  j                  ||      S r   )r   r   r&   __setitem__)r)   rS   r-   s      r   r   zEIP712Struct.__setitem__"  s7    ""3'""3.{{&&sE22r   c                     t        d      )Nz5Deleting entries from an EIP712Struct is not allowed.)	TypeError)r)   _s     r   __delitem__zEIP712Struct.__delitem__)  s    OPPr   c                     |sy| |u ryt        |t              sy| j                         |j                         k(  xr! | j                         |j                         k(  S )NFT)r(   r   re   r9   )r)   others     r   __eq__zEIP712Struct.__eq__,  s[    5=%. !U%6%6%88hT=N=N=PTYTfTfTh=hhr   c                     | j                   j                         D cg c]  \  }}t        |      t        |      z   }}}t        j                  t
        j                  |t        | j                              S c c}}w r   )r&   rA   hash	functoolsreduceoperatorxorr#   )r)   rD   rE   value_hashess       r   __hash__zEIP712Struct.__hash__:  s[    6:kk6G6G6IJdaQ$q')JJlD<PQQ Ks   !A:r   )&r   r   r   r   r"   r   r0   r9   r6   r?   rB   boolstrrW   rU   re   bytesrh   r8   r   r   r
   r$   staticmethodrq   r%   rw   r{   r}   r   r   r   r   r   r   r   r   __classcell__)r.   s   @r   r   r      s   	& % %(&%
& 
d 
s 
 
 = = & & .% . .IU I DsJ!78    ! !4 !F9n 9 9^ u  7 7 7 7r G G
 Q Q",
3QiRr   r   )	metaclassc                   "    e Zd ZU eed<   eed<   y)r   ru   rp   N)r   r   r   r   __annotations__r   r   r   r   r   ?  s    r   r   )r   ry   r   r   collectionsr   r   typingr   r   r   eth_utils.cryptor   rm   poly_eip712_structs.typesr	   r
   r   r   r4   r   r   r   r   r   r   <module>r      sR       	 0 * * #  ] ]D fR:)> fRR	* r   