11using  System . Numerics ; 
22using  Nethereum . ABI . EIP712 ; 
33using  Nethereum . Hex . HexConvertors . Extensions ; 
4+ using  Nethereum . Hex . HexTypes ; 
45using  Nethereum . Model ; 
56using  Nethereum . RLP ; 
67using  Nethereum . Signer ; 
@@ -48,14 +49,15 @@ public static async Task<string> GenerateSignature_ZkSyncTransaction(
4849            IThirdwebWallet  signer 
4950        ) 
5051        { 
51-             var  typedData  =  GetTypedDefinition_ZkSyncTransaction ( domainName ,  version ,  chainId ,  transaction . From ) ; 
52- 
53-             var  typedDataSigner  =  new  Eip712TypedDataSigner ( ) ; 
54-             var  encodedTypedData  =  typedDataSigner . EncodeTypedData ( transaction ,  typedData ) ; 
55-             var  hash  =  new  Sha3Keccack ( ) . CalculateHash ( encodedTypedData ) ; 
52+             var  typedData  =  GetTypedDefinition_ZkSyncTransaction ( domainName ,  version ,  chainId ) ; 
53+             var  typedDataEncoder  =  new  Eip712TypedDataEncoder ( ) ; 
54+             var  hash  =  typedDataEncoder . EncodeAndHashTypedData ( transaction ,  typedData ) ; 
55+             Console . WriteLine ( $ "Hash: { hash . ToHex ( true ) } ") ; 
5656            var  signatureHex  =  await  signer . EthSign ( hash ) ; 
57-             var  signatureRaw  =  ECDSASignatureFactory . ExtractECDSASignature ( signatureHex ) ; 
57+             Console . WriteLine ( $ "Signature: { signatureHex } ") ; 
58+             var  signatureRaw  =  EthECDSASignatureFactory . ExtractECDSASignature ( signatureHex ) ; 
5859            var  serializedTx  =  SerializeEip712 ( transaction ,  signatureRaw ,  signatureHex ,  chainId ) ; 
60+             Console . WriteLine ( $ "Serialized: { serializedTx } ") ; 
5961            return  serializedTx ; 
6062        } 
6163
@@ -91,23 +93,22 @@ public static TypedData<Domain> GetTypedDefinition_SmartAccount_AccountMessage(s
9193            } ; 
9294        } 
9395
94-         public  static   TypedData < Domain >  GetTypedDefinition_ZkSyncTransaction ( string  domainName ,  string  version ,  BigInteger  chainId ,   string   verifyingContract ) 
96+         public  static   TypedData < DomainWithNameVersionAndChainId >  GetTypedDefinition_ZkSyncTransaction ( string  domainName ,  string  version ,  BigInteger  chainId ) 
9597        { 
96-             return  new  TypedData < Domain > 
98+             return  new  TypedData < DomainWithNameVersionAndChainId > 
9799            { 
98-                 Domain  =  new  Domain 
100+                 Domain  =  new  DomainWithNameVersionAndChainId 
99101                { 
100102                    Name  =  domainName , 
101103                    Version  =  version , 
102104                    ChainId  =  chainId , 
103-                     VerifyingContract  =  verifyingContract 
104105                } , 
105-                 Types  =  MemberDescriptionFactory . GetTypesMemberDescription ( typeof ( Domain ) ,  typeof ( AccountAbstraction . ZkSyncAATransaction ) ) , 
106+                 Types  =  MemberDescriptionFactory . GetTypesMemberDescription ( typeof ( DomainWithNameVersionAndChainId ) ,  typeof ( AccountAbstraction . ZkSyncAATransaction ) ) , 
106107                PrimaryType  =  nameof ( AccountAbstraction . ZkSyncAATransaction ) , 
107108            } ; 
108109        } 
109110
110-         private  static   string  SerializeEip712 ( AccountAbstraction . ZkSyncAATransaction  transaction ,  ECDSASignature  signature ,  string  signatureHex ,  BigInteger  chainId ) 
111+         private  static   string  SerializeEip712 ( AccountAbstraction . ZkSyncAATransaction  transaction ,  EthECDSASignature  signature ,  string  signatureHex ,  BigInteger  chainId ) 
111112        { 
112113            if  ( chainId  ==  0 ) 
113114            { 
@@ -119,27 +120,53 @@ private static string SerializeEip712(AccountAbstraction.ZkSyncAATransaction tra
119120                throw  new  ArgumentException ( "From address must be provided for EIP712 transactions!" ) ; 
120121            } 
121122
122-             return  "0x71" 
123-                 +  RLP . EncodeList ( 
124-                         transaction . Nonce . ToBytesForRLPEncoding ( ) , 
125-                         transaction . MaxPriorityFeePerGas . ToBytesForRLPEncoding ( ) , 
126-                         transaction . MaxFeePerGas . ToBytesForRLPEncoding ( ) , 
127-                         transaction . GasLimit . ToBytesForRLPEncoding ( ) , 
128-                         transaction . To . ToBytesForRLPEncoding ( ) , 
129-                         transaction . Value . ToBytesForRLPEncoding ( ) , 
130-                         transaction . Data . ToHex ( ) . ToBytesForRLPEncoding ( ) , 
131-                         signature . V . ToHex ( ) . ToBytesForRLPEncoding ( ) , 
132-                         signature . R . ToByteArray ( ) . ToHex ( ) . ToBytesForRLPEncoding ( ) , 
133-                         signature . S . ToByteArray ( ) . ToHex ( ) . ToBytesForRLPEncoding ( ) , 
134-                         chainId . ToBytesForRLPEncoding ( ) , 
135-                         transaction . From . ToBytesForRLPEncoding ( ) , 
136-                         transaction . GasPerPubdataByteLimit . ToBytesForRLPEncoding ( ) , 
137-                         transaction . FactoryDeps . ToHex ( ) . ToBytesForRLPEncoding ( )  ??  Array . Empty < byte > ( ) . ToHex ( ) . ToBytesForRLPEncoding ( ) , 
138-                         signatureHex . ToBytesForRLPEncoding ( ) , 
139-                         transaction . Paymaster . ToBytesForRLPEncoding ( ) , 
140-                         transaction . PaymasterInput . ToHex ( ) . ToBytesForRLPEncoding ( ) 
141-                     ) 
142-                     . ToHex ( ) ; 
123+             var  fields  =  new  List < byte [ ] > 
124+             { 
125+                 transaction . Nonce . ToByteArray ( isUnsigned :  true ,  isBigEndian :  true ) , 
126+                 transaction . MaxPriorityFeePerGas . ToByteArray ( isUnsigned :  true ,  isBigEndian :  true ) , 
127+                 transaction . MaxFeePerGas . ToByteArray ( isUnsigned :  true ,  isBigEndian :  true ) , 
128+                 transaction . GasLimit . ToByteArray ( isUnsigned :  true ,  isBigEndian :  true ) , 
129+                 transaction . To . HexToByteArray ( ) , 
130+                 transaction . Value  ==  0  ?  new  byte [ 0 ]  :  transaction . Value . ToByteArray ( isUnsigned :  true ,  isBigEndian :  true ) , 
131+                 transaction . Data  ==  null  ?  new  byte [ 0 ]  :  transaction . Data , 
132+             } ; 
133+ 
134+             if  ( signature  !=  null ) 
135+             { 
136+                 fields . Add ( new  BigInteger ( signature . V ) . ToByteArray ( isUnsigned :  false ,  isBigEndian :  true ) ) ; 
137+                 fields . Add ( new  BigInteger ( signature . R ) . ToByteArray ( isUnsigned :  false ,  isBigEndian :  true ) ) ; 
138+                 fields . Add ( new  BigInteger ( signature . S ) . ToByteArray ( isUnsigned :  false ,  isBigEndian :  true ) ) ; 
139+             } 
140+             else 
141+             { 
142+                 fields . Add ( chainId . ToByteArray ( isUnsigned :  true ,  isBigEndian :  true ) ) ; 
143+                 fields . Add ( new  byte [ 0 ] ) ; 
144+                 fields . Add ( new  byte [ 0 ] ) ; 
145+             } 
146+ 
147+             fields . Add ( chainId . ToByteArray ( isUnsigned :  true ,  isBigEndian :  true ) ) ; 
148+             fields . Add ( transaction . From . HexToByteArray ( ) ) ; 
149+ 
150+             // Add meta 
151+             fields . Add ( transaction . GasPerPubdataByteLimit . ToByteArray ( isUnsigned :  true ,  isBigEndian :  true ) ) ; 
152+             fields . Add ( RLP . EncodeList ( transaction . FactoryDeps ) ) ; 
153+             fields . Add ( signatureHex . HexToByteArray ( ) ) ; 
154+ 
155+             if  ( ! string . IsNullOrEmpty ( transaction . Paymaster )  &&  transaction . PaymasterInput  !=  null ) 
156+             { 
157+                 fields . Add ( transaction . Paymaster . HexToByteArray ( ) ) ; 
158+                 fields . Add ( transaction . PaymasterInput ) ; 
159+             } 
160+             else 
161+             { 
162+                 fields . Add ( new  byte [ 0 ] ) ; 
163+             } 
164+ 
165+             // 0x71f901250c84017d784084017d78408401312d009483e13cd6b1179be8b8cb5858accbba84394cf9a780801ca095bdae3d9ee4919b95ccb65008fb834b876cf6daab54f08914a3682b692dac3ba007de707e93d03249ffcaac274caf27e513cbe96d78d24c0136ab8a2aae94a66782012c9483e13cd6b1179be8b8cb5858accbba84394cf9a782c35081c0b8413bac2d692b68a31489f054abdaf66c874b83fb0850b6cc959b91e49e3daebd9567a694ae2a8aab36014cd2786de9cb13e527af4c27accaff4932d0937e70de071c94ba226d47cbb2731cbaa67c916c57d68484aa269fb8448c5a344500000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000 
166+ 
167+             // 0x71f901260c84017d784084017d78408401312d009483e13cd6b1179be8b8cb5858accbba84394cf9a7808080a02ce7dea3c25ac28c69ef5d425933bf6195c7c5648e4e228e3dca1f62f147449ea06b626df4ccad17b8c472ddba39b113c0e8f49569572fdd4ac2f6e2ddfc29726682012c9483e13cd6b1179be8b8cb5858accbba84394cf9a782c350c0b8412ce7dea3c25ac28c69ef5d425933bf6195c7c5648e4e228e3dca1f62f147449e6b626df4ccad17b8c472ddba39b113c0e8f49569572fdd4ac2f6e2ddfc2972661bf85b94ba226d47cbb2731cbaa67c916c57d68484aa269fb8448c5a344500000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000 
168+ 
169+             return  "0x71"  +  RLP . EncodeDataItemsAsElementOrListAndCombineAsList ( fields . ToArray ( ) ) . ToHex ( ) ; 
143170        } 
144171    } 
145172} 
0 commit comments