@@ -3,7 +3,7 @@ const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers');
3
3
4
4
const { getDomain } = require ( '@openzeppelin/contracts/test/helpers/eip712' ) ;
5
5
const { ERC4337Helper } = require ( '../helpers/erc4337' ) ;
6
- const { NonNativeSigner, P256SigningKey, RSASHA256SigningKey } = require ( '../helpers/signers' ) ;
6
+ const { NonNativeSigner, P256SigningKey, RSASHA256SigningKey, ZKEmailSigningKey } = require ( '../helpers/signers' ) ;
7
7
const { PackedUserOperation } = require ( '../helpers/eip712-types' ) ;
8
8
9
9
const { shouldBehaveLikeAccountCore, shouldBehaveLikeAccountHolder } = require ( './Account.behavior' ) ;
@@ -15,15 +15,36 @@ const signerECDSA = ethers.Wallet.createRandom();
15
15
const signerP256 = new NonNativeSigner ( P256SigningKey . random ( ) ) ;
16
16
const signerRSA = new NonNativeSigner ( RSASHA256SigningKey . random ( ) ) ;
17
17
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
+
18
26
// Minimal fixture common to the different signer verifiers
19
27
async function fixture ( ) {
20
28
// EOAs and environment
21
- const [ beneficiary , other ] = await ethers . getSigners ( ) ;
29
+ const [ admin , beneficiary , other ] = await ethers . getSigners ( ) ;
22
30
const target = await ethers . deployContract ( 'CallReceiverMockExtended' ) ;
23
31
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
+
24
44
// ERC-7913 verifiers
25
45
const verifierP256 = await ethers . deployContract ( 'ERC7913SignatureVerifierP256' ) ;
26
46
const verifierRSA = await ethers . deployContract ( 'ERC7913SignatureVerifierRSA' ) ;
47
+ const verifierZKEmail = await ethers . deployContract ( '$ERC7913SignatureVerifierZKEmail' ) ;
27
48
28
49
// ERC-4337 env
29
50
const helper = new ERC4337Helper ( ) ;
@@ -43,7 +64,20 @@ async function fixture() {
43
64
. then ( signature => Object . assign ( userOp , { signature } ) ) ;
44
65
} ;
45
66
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
+ } ;
47
81
}
48
82
49
83
describe ( 'AccountERC7913' , function ( ) {
@@ -103,4 +137,36 @@ describe('AccountERC7913', function () {
103
137
shouldBehaveLikeERC1271 ( { erc7739 : true } ) ;
104
138
shouldBehaveLikeERC7821 ( ) ;
105
139
} ) ;
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
+ } ) ;
106
172
} ) ;
0 commit comments