EIP712.test.js 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. const ethSigUtil = require('eth-sig-util');
  2. const Wallet = require('ethereumjs-wallet').default;
  3. const EIP712 = artifacts.require('EIP712External');
  4. const EIP712Domain = [
  5. { name: 'name', type: 'string' },
  6. { name: 'version', type: 'string' },
  7. { name: 'chainId', type: 'uint256' },
  8. { name: 'verifyingContract', type: 'address' },
  9. ];
  10. async function domainSeparator (name, version, chainId, verifyingContract) {
  11. return '0x' + ethSigUtil.TypedDataUtils.hashStruct(
  12. 'EIP712Domain',
  13. { name, version, chainId, verifyingContract },
  14. { EIP712Domain },
  15. ).toString('hex');
  16. }
  17. contract('EIP712', function (accounts) {
  18. const [mailTo] = accounts;
  19. const name = 'A Name';
  20. const version = '1';
  21. beforeEach('deploying', async function () {
  22. this.eip712 = await EIP712.new(name, version);
  23. // We get the chain id from the contract because Ganache (used for coverage) does not return the same chain id
  24. // from within the EVM as from the JSON RPC interface.
  25. // See https://github.com/trufflesuite/ganache-core/issues/515
  26. this.chainId = await this.eip712.getChainId();
  27. });
  28. it('domain separator', async function () {
  29. expect(
  30. await this.eip712.domainSeparator(),
  31. ).to.equal(
  32. await domainSeparator(name, version, this.chainId, this.eip712.address),
  33. );
  34. });
  35. it('digest', async function () {
  36. const chainId = this.chainId;
  37. const verifyingContract = this.eip712.address;
  38. const message = {
  39. to: mailTo,
  40. contents: 'very interesting',
  41. };
  42. const data = {
  43. types: {
  44. EIP712Domain,
  45. Mail: [
  46. { name: 'to', type: 'address' },
  47. { name: 'contents', type: 'string' },
  48. ],
  49. },
  50. domain: { name, version, chainId, verifyingContract },
  51. primaryType: 'Mail',
  52. message,
  53. };
  54. const wallet = Wallet.generate();
  55. const signature = ethSigUtil.signTypedMessage(wallet.getPrivateKey(), { data });
  56. await this.eip712.verify(signature, wallet.getAddressString(), message.to, message.contents);
  57. });
  58. });