Skip to content

Commit

Permalink
✨ feat: Encrypt/decrypt using MetaMask (#1109)
Browse files Browse the repository at this point in the history
## Motivation and context

Implemented encrypt/decrypt functionalities using MetaMask.

## Does it fix any issue?

https://linear.app/synpress/issue/SYN-63/encryptdecrypt

- [x] I have performed a self-review of my code.
- [x] If it is a core feature, I have added thorough e2e tests.

**⚠️👆 Delete any section you see irrelevant before submitting the pull request 👆⚠️**


---

<details open="true"><summary>Generated summary</summary>

> ### TL;DR
> This pull request adds new methods to MetaMask class for adding new tokens, providing public encryption keys, and decrypting messages. It also includes new actions for encryption in the NotificationPage.
> 
> ### What changed
> - Added new methods `addNewToken()`, `providePublicEncryptionKey()`, and `decrypt()` to the MetaMask class.
> - Added new actions for encryption in the NotificationPage.
> - Created new files for encryption actions in the NotificationPage.
> 
> ### How to test
> 1. Click on the 'getEncryptionKeyButton' button to provide a public encryption key.
> 2. Verify that the encryption key is displayed correctly.
> 3. Encrypt and decrypt a message by following the steps provided in the test cases.
> 
> ### Why make this change
> - This change introduces new functionality to MetaMask for handling encryption tasks.
> - The addition of encryption actions in the NotificationPage enhances the security features of the application.
> - These changes improve the overall user experience and security of MetaMask.
</details>
  • Loading branch information
matstyler authored Feb 28, 2024
1 parent 21e8efa commit c664eb7
Show file tree
Hide file tree
Showing 7 changed files with 88 additions and 11 deletions.
32 changes: 24 additions & 8 deletions wallets/metamask/src/metamask.ts
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,30 @@ export class MetaMask {
await this.settingsPage.disableEthSign()
}

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

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

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

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

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

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

/// -------------------------------------------
/// ---------- EXPERIMENTAL FEATURES ----------
/// -------------------------------------------
Expand Down Expand Up @@ -429,12 +453,4 @@ export class MetaMask {
async closeTransactionDetails() {
await this.homePage.closeTransactionDetails()
}

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

await this.notificationPage.addNewToken(this.extensionId)
}
}
10 changes: 10 additions & 0 deletions wallets/metamask/src/pages/NotificationPage/actions/encryption.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import type { Page } from '@playwright/test'
import Selectors from '../selectors'

export async function providePublicEncryptionKey(notificationPage: Page) {
await notificationPage.locator(Selectors.ActionFooter.confirmActionButton).click()
}

export async function decryptMessage(notificationPage: Page) {
await notificationPage.locator(Selectors.ActionFooter.confirmActionButton).click()
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ export * from './approvePermission'
export * from './transaction'
export * from './network'
export * from './token'
export * from './encryption'
14 changes: 14 additions & 0 deletions wallets/metamask/src/pages/NotificationPage/page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ import {
type GasSetting,
approvePermission,
connectToDapp,
decryptMessage,
network,
providePublicEncryptionKey,
signSimpleMessage,
signStructuredMessage,
token,
Expand Down Expand Up @@ -139,4 +141,16 @@ export class NotificationPage {

await token.addNew(notificationPage)
}

async providePublicEncryptionKey(extensionId: string) {
const notificationPage = await getNotificationPageAndWaitForLoad(this.page.context(), extensionId)

await providePublicEncryptionKey(notificationPage)
}

async decryptMessage(extensionId: string) {
const notificationPage = await getNotificationPageAndWaitForLoad(this.page.context(), extensionId)

await decryptMessage(notificationPage)
}
}
4 changes: 2 additions & 2 deletions wallets/metamask/src/pages/OnboardingPage/selectors/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,5 @@ export default {
WalletCreationSuccessPageSelectors,

// 5th Page
PinExtensionPageSelectors
}
PinExtensionPageSelectors,
};
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ export async function getNotificationPageAndWaitForLoad(context: BrowserContext,
let notificationPage = context.pages().find(isNotificationPage)

if (!notificationPage) {
notificationPage = await context.waitForEvent('page', { predicate: isNotificationPage })
notificationPage = await context.waitForEvent('page', {
predicate: isNotificationPage
})
}

// Set pop-up window viewport size to resemble the actual MetaMask pop-up window.
Expand Down
34 changes: 34 additions & 0 deletions wallets/metamask/test/e2e/metamask/encrypt.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { testWithMetaMask } from '../testWithMetaMask'

const test = testWithMetaMask

const { expect } = test

test('should provide public encryption key', async ({ page, metamask }) => {
await page.locator('#getEncryptionKeyButton').click()
await metamask.providePublicEncryptionKey()

await expect(page.locator('#encryptionKeyDisplay')).toHaveText('mtrHp1WHZM9rxF2Ilot9Hie5XmQcKCf7oDQ1DpGkTSI=')
})

test('should encrypt and decrypt a message', async ({ page, metamask }) => {
await page.locator('#getEncryptionKeyButton').click()
await metamask.providePublicEncryptionKey()
await expect(page.locator('#encryptionKeyDisplay')).toHaveText('mtrHp1WHZM9rxF2Ilot9Hie5XmQcKCf7oDQ1DpGkTSI=')

// `fill` does not trigger buttons validation, so we use `type` instead
await page.locator('#encryptMessageInput').type('Hello, world')

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

const encryptedMessage = await page.locator('#ciphertextDisplay').textContent()

expect(encryptedMessage).toContain('0x7b')

await page.locator('#decryptButton').click()
await metamask.decrypt()

const decryptedMessage = await page.locator('#cleartextDisplay').textContent()

expect(decryptedMessage).toEqual('Hello, world')
})

0 comments on commit c664eb7

Please sign in to comment.