AccountERC7913.test.js 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. const { ethers, predeploy } = 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, WebAuthnSigningKey } = 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. const signerWebAuthn = new NonNativeSigner(WebAuthnSigningKey.random());
  15. // Minimal fixture common to the different signer verifiers
  16. async function fixture() {
  17. // EOAs and environment
  18. const [beneficiary, other] = await ethers.getSigners();
  19. const target = await ethers.deployContract('CallReceiverMock');
  20. // ERC-7913 verifiers
  21. const verifierP256 = await ethers.deployContract('ERC7913P256Verifier');
  22. const verifierRSA = await ethers.deployContract('ERC7913RSAVerifier');
  23. const verifierWebAuthn = await ethers.deployContract('ERC7913WebAuthnVerifier');
  24. // ERC-4337 env
  25. const helper = new ERC4337Helper();
  26. await helper.wait();
  27. const entrypointDomain = await getDomain(predeploy.entrypoint.v08);
  28. const domain = { name: 'AccountERC7913', version: '1', chainId: entrypointDomain.chainId }; // Missing verifyingContract,
  29. const makeMock = signer =>
  30. helper.newAccount('$AccountERC7913Mock', [signer, 'AccountERC7913', '1']).then(mock => {
  31. domain.verifyingContract = mock.address;
  32. return mock;
  33. });
  34. const signUserOp = function (userOp) {
  35. return this.signer
  36. .signTypedData(entrypointDomain, { PackedUserOperation }, userOp.packed)
  37. .then(signature => Object.assign(userOp, { signature }));
  38. };
  39. return {
  40. helper,
  41. verifierP256,
  42. verifierRSA,
  43. verifierWebAuthn,
  44. domain,
  45. target,
  46. beneficiary,
  47. other,
  48. makeMock,
  49. signUserOp,
  50. };
  51. }
  52. describe('AccountERC7913', function () {
  53. beforeEach(async function () {
  54. Object.assign(this, await loadFixture(fixture));
  55. });
  56. // Using ECDSA key as verifier
  57. describe('ECDSA key', function () {
  58. beforeEach(async function () {
  59. this.signer = signerECDSA;
  60. this.mock = await this.makeMock(this.signer.address);
  61. });
  62. shouldBehaveLikeAccountCore();
  63. shouldBehaveLikeAccountHolder();
  64. shouldBehaveLikeERC1271({ erc7739: true });
  65. shouldBehaveLikeERC7821();
  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. shouldBehaveLikeAccountCore();
  80. shouldBehaveLikeAccountHolder();
  81. shouldBehaveLikeERC1271({ erc7739: true });
  82. shouldBehaveLikeERC7821();
  83. });
  84. // Using RSA key with an ERC-7913 verifier
  85. describe('RSA key', function () {
  86. beforeEach(async function () {
  87. this.signer = signerRSA;
  88. this.mock = await this.makeMock(
  89. ethers.concat([
  90. this.verifierRSA.target,
  91. ethers.AbiCoder.defaultAbiCoder().encode(
  92. ['bytes', 'bytes'],
  93. [this.signer.signingKey.publicKey.e, this.signer.signingKey.publicKey.n],
  94. ),
  95. ]),
  96. );
  97. });
  98. shouldBehaveLikeAccountCore();
  99. shouldBehaveLikeAccountHolder();
  100. shouldBehaveLikeERC1271({ erc7739: true });
  101. shouldBehaveLikeERC7821();
  102. });
  103. // Using WebAuthn key with an ERC-7913 verifier
  104. describe('WebAuthn key', function () {
  105. beforeEach(async function () {
  106. this.signer = signerWebAuthn;
  107. this.mock = await this.makeMock(
  108. ethers.concat([
  109. this.verifierWebAuthn.target,
  110. this.signer.signingKey.publicKey.qx,
  111. this.signer.signingKey.publicKey.qy,
  112. ]),
  113. );
  114. });
  115. shouldBehaveLikeAccountCore();
  116. shouldBehaveLikeAccountHolder();
  117. shouldBehaveLikeERC1271({ erc7739: true });
  118. shouldBehaveLikeERC7821();
  119. });
  120. });