AccountERC7913.test.js 3.7 KB

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