Skip to content

Commit

Permalink
✨ feat: eth_sign, MetaMask settings page
Browse files Browse the repository at this point in the history
  • Loading branch information
matstyler committed Feb 22, 2024
1 parent f368fd8 commit 7002461
Show file tree
Hide file tree
Showing 10 changed files with 136 additions and 5 deletions.
21 changes: 21 additions & 0 deletions wallets/metamask/src/metamask.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { CrashPage, HomePage, LockPage, NotificationPage, OnboardingPage } from
import type { Network } from './pages/HomePage/actions'
import { SettingsSidebarMenus } from './pages/HomePage/selectors/settings'
import type { GasSetting } from './pages/NotificationPage/actions'
import { SettingsPage } from './pages/SettingsPage/page'

const NO_EXTENSION_ID_ERROR = new Error('MetaMask extensionId is not set')

Expand Down Expand Up @@ -40,6 +41,7 @@ export class MetaMask {
* @group Selectors
*/
readonly notificationPage: NotificationPage
readonly settingsPage: SettingsPage

/**
* Class constructor.
Expand Down Expand Up @@ -75,6 +77,7 @@ export class MetaMask {
this.lockPage = new LockPage(page)
this.homePage = new HomePage(page)
this.notificationPage = new NotificationPage(page)
this.settingsPage = new SettingsPage(page)
}

/**
Expand Down Expand Up @@ -173,6 +176,14 @@ export class MetaMask {
await this.notificationPage.signMessage(this.extensionId)
}

async confirmSignatureWithRisk() {
if (!this.extensionId) {
throw NO_EXTENSION_ID_ERROR
}

await this.notificationPage.signMessageWithRisk(this.extensionId)
}

/**
* Rejects a signature request. This function supports all types of commonly used signatures.
*/
Expand Down Expand Up @@ -346,6 +357,16 @@ export class MetaMask {
await this.homePage.resetAccount()
}

async unsafe_enableEthSign() {
await this.homePage.openSettings()
await this.settingsPage.enableEthSign()
}

async disableEthSign() {
await this.homePage.openSettings()
await this.settingsPage.disableEthSign()
}

/// -------------------------------------------
/// ---------- EXPERIMENTAL FEATURES ----------
/// -------------------------------------------
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,14 @@ const rejectMessage = async (notificationPage: Page) => {
await notificationPage.locator(Selectors.ActionFooter.rejectActionButton).click()
}

// Used for:
// - `personal_sign`
// - `eth_signTypedData`
const signMessageWithRisk = async (notificationPage: Page) => {
await signMessage(notificationPage)

await notificationPage.locator(Selectors.SignaturePage.riskModal.signButton).click()
}

export const signSimpleMessage = {
sign: signMessage,
reject: rejectMessage
reject: rejectMessage,
signWithRisk: signMessageWithRisk
}
6 changes: 6 additions & 0 deletions wallets/metamask/src/pages/NotificationPage/page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,12 @@ export class NotificationPage {
}
}

async signMessageWithRisk(extensionId: string) {
const { notificationPage } = await this.beforeMessageSignature(extensionId)

await signSimpleMessage.signWithRisk(notificationPage)
}

async rejectMessage(extensionId: string) {
const { notificationPage, isScrollButtonVisible } = await this.beforeMessageSignature(extensionId)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,12 @@ const structuredMessage = {
rejectButton: `.signature-request-footer ${createDataTestSelector('signature-cancel-button')}`
}

const riskModal = {
signButton: createDataTestSelector('signature-warning-sign-button')
}

export default {
simpleMessage,
structuredMessage
structuredMessage,
riskModal
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import type { Page } from '@playwright/test'
import Selectors from '../selectors'

export default async function disableEthSign(page: Page) {
await page.locator(Selectors.settings.advancedSettings).click()
await page.locator(Selectors.settings.ethSignToggle).click()
}
18 changes: 18 additions & 0 deletions wallets/metamask/src/pages/SettingsPage/actions/enableEthSign.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import type { Page } from '@playwright/test'
import Selectors from '../selectors'

export default async function enableEthSign(page: Page) {
// Settings
await page.locator(Selectors.settings.advancedSettings).click()
await page.locator(Selectors.settings.ethSignToggle).click()

// Confirmation modal
await page.locator(Selectors.confirmationModal.confirmationCheckbox).click()
await page.locator(Selectors.confirmationModal.continueButton).click()
await page.locator(Selectors.confirmationModal.manualConfirmationInput).focus()
await page.locator(Selectors.confirmationModal.manualConfirmationInput).fill('I only sign what I understand')
await page.locator(Selectors.confirmationModal.enableButton).click()

// Wait for warning
await page.locator(Selectors.settings.ethSignWarning).isVisible()
}
2 changes: 2 additions & 0 deletions wallets/metamask/src/pages/SettingsPage/actions/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { default as enableEthSign } from './enableEthSign'
export { default as disableEthSign } from './disableEthSign'
22 changes: 22 additions & 0 deletions wallets/metamask/src/pages/SettingsPage/page.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import type { Page } from '@playwright/test'
import { enableEthSign } from './actions'
import Selectors from './selectors'
import disableEthSign from './actions/disableEthSign'

export class SettingsPage {
static readonly selectors = Selectors

readonly page: Page

constructor(page: Page) {
this.page = page
}

async enableEthSign() {
await enableEthSign(this.page)
}

async disableEthSign() {
await disableEthSign(this.page)
}
}
23 changes: 23 additions & 0 deletions wallets/metamask/src/pages/SettingsPage/selectors/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { createDataTestSelector } from '../../../utils/selectors/createDataTestSelector'

const menuOption = '.settings-page__content__tabs .tab-bar .tab-bar__tab'

const settings = {
menuOption,
advancedSettings: `${menuOption}:nth-child(2)`,
ethSignToggle: `${createDataTestSelector('advanced-setting-toggle-ethsign')} .eth-sign-toggle`,
ethSignWarning:
'.settings-page__content-row .mm-banner-alert.mm-banner-alert--severity-danger.mm-box--background-color-error-muted'
}

const confirmationModal = {
confirmationCheckbox: createDataTestSelector('eth-sign__checkbox'),
continueButton: '.modal__content button.mm-button-primary',
manualConfirmationInput: '#enter-eth-sign-text',
enableButton: '.modal__content button.mm-button-primary.mm-button-primary--type-danger'
}

export default {
settings,
confirmationModal
}
23 changes: 23 additions & 0 deletions wallets/metamask/test/e2e/metamask/confirmSignature.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,26 @@ test('should confirm `eth_signTypedData_v4`', async ({ page, metamask }) => {

await expect(page.locator('#signTypedDataV4VerifyResult')).toHaveText('0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266')
})

test('should confirm `eth_sign`', async ({ page, metamask }) => {
await metamask.unsafe_enableEthSign()

await page.locator('#ethSign').click()

await metamask.confirmSignatureWithRisk()

await expect(page.locator('#ethSignResult')).toContainText(
'0xbfefd81020331aa2869403ba11711f082506b9c9313c29a212975067123ca222536ba40b17d8847356cc4ee448fb088231db98632e745e469f7e3d142e4256541b'
)
})

test('should not be permitted to confirm `eth_sign`', async ({ page, metamask }) => {
await metamask.unsafe_enableEthSign()
await metamask.disableEthSign()

await page.locator('#ethSign').click()

await expect(page.locator('#ethSign')).toContainText(
'Error: eth_sign has been disabled. You must enable it in the advanced settings'
)
})

0 comments on commit 7002461

Please sign in to comment.