@@ -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("test@example.com")
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