@@ -3,7 +3,7 @@ const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers');
33
44const  {  getDomain }  =  require ( '@openzeppelin/contracts/test/helpers/eip712' ) ; 
55const  {  ERC4337Helper }  =  require ( '../helpers/erc4337' ) ; 
6- const  {  NonNativeSigner,  P256SigningKey,  RSASHA256SigningKey }  =  require ( '../helpers/signers' ) ; 
6+ const  {  NonNativeSigner,  P256SigningKey,  RSASHA256SigningKey,  ZKEmailSigningKey  }  =  require ( '../helpers/signers' ) ; 
77const  {  PackedUserOperation }  =  require ( '../helpers/eip712-types' ) ; 
88
99const  {  shouldBehaveLikeAccountCore,  shouldBehaveLikeAccountHolder }  =  require ( './Account.behavior' ) ; 
@@ -15,15 +15,36 @@ const signerECDSA = ethers.Wallet.createRandom();
1515const  signerP256  =  new  NonNativeSigner ( P256SigningKey . random ( ) ) ; 
1616const  signerRSA  =  new  NonNativeSigner ( RSASHA256SigningKey . random ( ) ) ; 
1717
18+ // Constants for ZKEmail 
19+ const  accountSalt  =  '0x046582bce36cdd0a8953b9d40b8f20d58302bacf3bcecffeb6741c98a52725e2' ;  // keccak256("[email protected] ") 20+ const  selector  =  '12345' ; 
21+ const  domainName  =  'gmail.com' ; 
22+ const  publicKeyHash  =  '0x0ea9c777dc7110e5a9e89b13f0cfc540e3845ba120b2b6dc24024d61488d4788' ; 
23+ const  emailNullifier  =  '0x00a83fce3d4b1c9ef0f600644c1ecc6c8115b57b1596e0e3295e2c5105fbfd8a' ; 
24+ const  templateId  =  ethers . solidityPackedKeccak256 ( [ 'string' ,  'uint256' ] ,  [ 'TEST' ,  0n ] ) ; 
25+ 
1826// Minimal fixture common to the different signer verifiers 
1927async  function  fixture ( )  { 
2028  // EOAs and environment 
21-   const  [ beneficiary ,  other ]  =  await  ethers . getSigners ( ) ; 
29+   const  [ admin ,   beneficiary ,  other ]  =  await  ethers . getSigners ( ) ; 
2230  const  target  =  await  ethers . deployContract ( 'CallReceiverMockExtended' ) ; 
2331
32+   // DKIM Registry for ZKEmail 
33+   const  dkim  =  await  ethers . deployContract ( 'ECDSAOwnedDKIMRegistry' ) ; 
34+   await  dkim . initialize ( admin ,  admin ) ; 
35+   await  dkim 
36+     . SET_PREFIX ( ) 
37+     . then ( prefix  =>  dkim . computeSignedMsg ( prefix ,  domainName ,  publicKeyHash ) ) 
38+     . then ( message  =>  admin . signMessage ( message ) ) 
39+     . then ( signature  =>  dkim . setDKIMPublicKeyHash ( selector ,  domainName ,  publicKeyHash ,  signature ) ) ; 
40+ 
41+   // ZKEmail Verifier 
42+   const  zkEmailVerifier  =  await  ethers . deployContract ( 'ZKEmailVerifierMock' ) ; 
43+ 
2444  // ERC-7913 verifiers 
2545  const  verifierP256  =  await  ethers . deployContract ( 'ERC7913SignatureVerifierP256' ) ; 
2646  const  verifierRSA  =  await  ethers . deployContract ( 'ERC7913SignatureVerifierRSA' ) ; 
47+   const  verifierZKEmail  =  await  ethers . deployContract ( '$ERC7913SignatureVerifierZKEmail' ) ; 
2748
2849  // ERC-4337 env 
2950  const  helper  =  new  ERC4337Helper ( ) ; 
@@ -43,7 +64,20 @@ async function fixture() {
4364      . then ( signature  =>  Object . assign ( userOp ,  {  signature } ) ) ; 
4465  } ; 
4566
46-   return  {  helper,  verifierP256,  verifierRSA,  domain,  target,  beneficiary,  other,  makeMock,  signUserOp } ; 
67+   return  { 
68+     helper, 
69+     verifierP256, 
70+     verifierRSA, 
71+     verifierZKEmail, 
72+     dkim, 
73+     zkEmailVerifier, 
74+     domain, 
75+     target, 
76+     beneficiary, 
77+     other, 
78+     makeMock, 
79+     signUserOp, 
80+   } ; 
4781} 
4882
4983describe ( 'AccountERC7913' ,  function  ( )  { 
@@ -103,4 +137,36 @@ describe('AccountERC7913', function () {
103137    shouldBehaveLikeERC1271 ( {  erc7739 : true  } ) ; 
104138    shouldBehaveLikeERC7821 ( ) ; 
105139  } ) ; 
140+ 
141+   // Using ZKEmail with an ERC-7913 verifier 
142+   describe ( 'ZKEmail' ,  function  ( )  { 
143+     beforeEach ( async  function  ( )  { 
144+       // Create ZKEmail signer 
145+       this . signer  =  new  NonNativeSigner ( 
146+         new  ZKEmailSigningKey ( domainName ,  publicKeyHash ,  emailNullifier ,  accountSalt ,  templateId ) , 
147+       ) ; 
148+ 
149+       // Create account with ZKEmail verifier 
150+       this . mock  =  await  this . makeMock ( 
151+         ethers . concat ( [ 
152+           this . verifierZKEmail . target , 
153+           ethers . AbiCoder . defaultAbiCoder ( ) . encode ( 
154+             [ 'address' ,  'bytes32' ,  'address' ,  'uint256' ] , 
155+             [ this . dkim . target ,  accountSalt ,  this . zkEmailVerifier . target ,  templateId ] , 
156+           ) , 
157+         ] ) , 
158+       ) ; 
159+ 
160+       // Override the signUserOp function to use the ZKEmail signer 
161+       this . signUserOp  =  async  userOp  =>  { 
162+         const  hash  =  await  userOp . hash ( ) ; 
163+         return  Object . assign ( userOp ,  {  signature : this . signer . signingKey . sign ( hash ) . serialized  } ) ; 
164+       } ; 
165+     } ) ; 
166+ 
167+     shouldBehaveLikeAccountCore ( ) ; 
168+     shouldBehaveLikeAccountHolder ( ) ; 
169+     shouldBehaveLikeERC1271 ( {  erc7739 : true  } ) ; 
170+     shouldBehaveLikeERC7821 ( ) ; 
171+   } ) ; 
106172} ) ; 
0 commit comments