@@ -3,59 +3,104 @@ 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 } = require ( '../helpers/signers' ) ;
6
+ const { NonNativeSigner, P256SigningKey, RSASHA256SigningKey } = require ( '../helpers/signers' ) ;
7
7
const { PackedUserOperation } = require ( '../helpers/eip712-types' ) ;
8
8
9
9
const { shouldBehaveLikeAccountCore, shouldBehaveLikeAccountHolder } = require ( './Account.behavior' ) ;
10
10
const { shouldBehaveLikeERC1271 } = require ( '../utils/cryptography/ERC1271.behavior' ) ;
11
11
const { shouldBehaveLikeERC7821 } = require ( './extensions/ERC7821.behavior' ) ;
12
12
13
+ // Prepare signer in advance (RSA are long to initialize)
14
+ const signerECDSA = ethers . Wallet . createRandom ( ) ;
15
+ const signerP256 = new NonNativeSigner ( P256SigningKey . random ( ) ) ;
16
+ const signerRSA = new NonNativeSigner ( RSASHA256SigningKey . random ( ) ) ;
17
+
18
+ // Minimal fixture common to the different signer verifiers
13
19
async function fixture ( ) {
14
20
// EOAs and environment
15
21
const [ beneficiary , other ] = await ethers . getSigners ( ) ;
16
22
const target = await ethers . deployContract ( 'CallReceiverMockExtended' ) ;
17
23
18
- // P256 signer
19
- const signer = new NonNativeSigner ( P256SigningKey . random ( ) ) ;
20
- const verifier = await ethers . deployContract ( 'ERC7913SignatureVerifierP256 ' ) ;
24
+ // ERC-7913 verifiers
25
+ const verifierP256 = await ethers . deployContract ( 'ERC7913SignatureVerifierP256' ) ;
26
+ const verifierRSA = await ethers . deployContract ( 'ERC7913SignatureVerifierRSA ' ) ;
21
27
22
- // ERC-4337 account
28
+ // ERC-4337 env
23
29
const helper = new ERC4337Helper ( ) ;
24
- const mock = await helper . newAccount ( '$AccountERC7913Mock' , [
25
- 'AccountERC7913' ,
26
- '1' ,
27
- ethers . solidityPacked (
28
- [ 'address' , 'bytes32' , 'bytes32' ] ,
29
- [ verifier . target , signer . signingKey . publicKey . qx , signer . signingKey . publicKey . qy ] ,
30
- ) ,
31
- ] ) ;
32
-
33
- // ERC-4337 Entrypoint domain
30
+ await helper . wait ( ) ;
34
31
const entrypointDomain = await getDomain ( entrypoint . v08 ) ;
32
+ const domain = { name : 'AccountERC7913' , version : '1' , chainId : entrypointDomain . chainId } ; // Missing verifyingContract,
35
33
36
- // domain cannot be fetched using getDomain(mock) before the mock is deployed
37
- const domain = {
38
- name : 'AccountERC7913' ,
39
- version : '1' ,
40
- chainId : entrypointDomain . chainId ,
41
- verifyingContract : mock . address ,
42
- } ;
34
+ const makeMock = signer =>
35
+ helper . newAccount ( '$AccountERC7913Mock' , [ 'AccountERC7913' , '1' , signer ] ) . then ( mock => {
36
+ domain . verifyingContract = mock . address ;
37
+ return mock ;
38
+ } ) ;
43
39
44
- const signUserOp = userOp =>
45
- signer
40
+ const signUserOp = function ( userOp ) {
41
+ return this . signer
46
42
. signTypedData ( entrypointDomain , { PackedUserOperation } , userOp . packed )
47
43
. then ( signature => Object . assign ( userOp , { signature } ) ) ;
44
+ } ;
48
45
49
- return { helper, mock , domain , signer , target, beneficiary, other, signUserOp } ;
46
+ return { helper, verifierP256 , verifierRSA , domain , target, beneficiary, other, makeMock , signUserOp } ;
50
47
}
51
48
52
49
describe ( 'AccountERC7913' , function ( ) {
53
50
beforeEach ( async function ( ) {
54
51
Object . assign ( this , await loadFixture ( fixture ) ) ;
55
52
} ) ;
56
53
57
- shouldBehaveLikeAccountCore ( ) ;
58
- shouldBehaveLikeAccountHolder ( ) ;
59
- shouldBehaveLikeERC1271 ( { erc7739 : true } ) ;
60
- shouldBehaveLikeERC7821 ( ) ;
54
+ // Using ECDSA key as verifier
55
+ describe ( 'ECDSA key' , function ( ) {
56
+ beforeEach ( async function ( ) {
57
+ this . signer = signerECDSA ;
58
+ this . mock = await this . makeMock ( this . signer . address ) ;
59
+ } ) ;
60
+
61
+ shouldBehaveLikeAccountCore ( ) ;
62
+ shouldBehaveLikeAccountHolder ( ) ;
63
+ shouldBehaveLikeERC1271 ( { erc7739 : true } ) ;
64
+ shouldBehaveLikeERC7821 ( ) ;
65
+ } ) ;
66
+
67
+ // Using P256 key with an ERC-7913 verifier
68
+ describe ( 'P256 key' , function ( ) {
69
+ beforeEach ( async function ( ) {
70
+ this . signer = signerP256 ;
71
+ this . mock = await this . makeMock (
72
+ ethers . concat ( [
73
+ this . verifierP256 . target ,
74
+ this . signer . signingKey . publicKey . qx ,
75
+ this . signer . signingKey . publicKey . qy ,
76
+ ] ) ,
77
+ ) ;
78
+ } ) ;
79
+
80
+ shouldBehaveLikeAccountCore ( ) ;
81
+ shouldBehaveLikeAccountHolder ( ) ;
82
+ shouldBehaveLikeERC1271 ( { erc7739 : true } ) ;
83
+ shouldBehaveLikeERC7821 ( ) ;
84
+ } ) ;
85
+
86
+ // Using RSA key with an ERC-7913 verifier
87
+ describe ( 'RSA key' , function ( ) {
88
+ beforeEach ( async function ( ) {
89
+ this . signer = signerRSA ;
90
+ this . mock = await this . makeMock (
91
+ ethers . concat ( [
92
+ this . verifierRSA . target ,
93
+ ethers . AbiCoder . defaultAbiCoder ( ) . encode (
94
+ [ 'bytes' , 'bytes' ] ,
95
+ [ this . signer . signingKey . publicKey . e , this . signer . signingKey . publicKey . n ] ,
96
+ ) ,
97
+ ] ) ,
98
+ ) ;
99
+ } ) ;
100
+
101
+ shouldBehaveLikeAccountCore ( ) ;
102
+ shouldBehaveLikeAccountHolder ( ) ;
103
+ shouldBehaveLikeERC1271 ( { erc7739 : true } ) ;
104
+ shouldBehaveLikeERC7821 ( ) ;
105
+ } ) ;
61
106
} ) ;
0 commit comments