// The sign screen signs an eth_sign request the way it signs personal_sign: as // an EIP-191 personal message over the bytes of the data // (https://git.eeqj.de/sneak/AutistMask/issues/409). Booted through the real // popup entry point as the approval window. The background's half, which reads // the address first and the data second and checks the signature, is tested in // tests/backgroundApproval.test.js. // Mocked so that no password has to be hashed: the stored secret decrypts to // the test key below. jest.mock("../src/shared/vault", () => ({ decryptWithPassword: jest.fn(), encryptWithPassword: jest.fn(), })); const { Wallet, getBytes } = require("ethers"); const { bootPopup, cleanupPopup, unversionedValidProfile, } = require("./support/popupBoot"); // A published test key, never used for real funds. const SIGNER_KEY = "0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d"; const signer = new Wallet(SIGNER_KEY); // "Hello AutistMask", as the hex a page sends. const MESSAGE = "0x48656c6c6f204175746973744d61736b"; const ORIGIN = "https://dapp.example"; afterEach(cleanupPopup); test("the sign screen answers eth_sign with a personal message signature over the data", async () => { const sent = []; const page = await bootPopup( unversionedValidProfile({ wallets: [ { type: "key", name: "Wallet 1", encryptedSecret: "encrypted-key", addresses: [ { address: signer.address, balance: "0.0000", tokenBalances: [], }, ], }, ], activeAddress: signer.address, allowedSites: { [signer.address]: [ORIGIN] }, }), { search: "?approval=approval-1", runtime: { connect: () => ({ postMessage: () => {} }), // Answered as the background answers: with the eth_sign // approval this window was opened for, and by handing back // the signature the popup sends. sendMessage: (msg, reply) => { sent.push(msg); if (msg.type === "AUTISTMASK_GET_APPROVAL") { reply({ type: "sign", origin: ORIGIN, isPhishingDomain: false, approvedFrom: signer.address, signParams: { method: "eth_sign", message: MESSAGE, from: signer.address, }, }); } else if (msg.type === "AUTISTMASK_SIGN_RESPONSE") { reply({ signature: msg.signature }); } else { reply(undefined); } }, }, }, ); globalThis.window.close = jest.fn(); const { decryptWithPassword } = require("../src/shared/vault"); decryptWithPassword.mockResolvedValue(SIGNER_KEY); expect(page.visibleViews()).toEqual(["approve-sign"]); page.node("approve-sign-password").value = "any password"; await page.click("btn-approve-sign"); expect( sent.filter((msg) => msg.type === "AUTISTMASK_SIGN_RESPONSE"), ).toEqual([ { type: "AUTISTMASK_SIGN_RESPONSE", id: "approval-1", approved: true, signature: await signer.signMessage(getBytes(MESSAGE)), }, ]); expect(globalThis.window.close).toHaveBeenCalled(); });