Skip to content

Commit

Permalink
feat: dapp initiated token transfer (#27875)
Browse files Browse the repository at this point in the history
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->

## **Description**

- Implements new header for dapp initiated token transfer confirmations
- Enables simulations component conditionally
- Includes e2e tests for said confirmation

<!--
Write a short description of the changes included in this pull request,
also include relevant motivation and context. Have in mind the following
questions:
1. What is the reason for the change?
2. What is the improvement/solution?
-->

[![Open in GitHub
Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/MetaMask/metamask-extension/pull/27875?quickstart=1)

## **Related issues**

Fixes: MetaMask/MetaMask-planning#3017

## **Manual testing steps**

1. Go to this page...
2.
3.

## **Screenshots/Recordings**

<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->

### **Before**

<!-- [screenshots/recordings] -->

### **After**

<!-- [screenshots/recordings] -->

<img width="472" alt="Screenshot 2024-10-15 at 16 20 37"
src="https://github.com/user-attachments/assets/2a15b02f-1fd3-467d-9d91-91fd90d27359">


## **Pre-merge author checklist**

- [ ] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask
Extension Coding
Standards](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/CODING_GUIDELINES.md).
- [ ] I've completed the PR template to the best of my ability
- [ ] I’ve included tests if applicable
- [ ] I’ve documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [ ] I’ve applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **Pre-merge reviewer checklist**

- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.
  • Loading branch information
pedronfigueiredo authored Oct 18, 2024
1 parent 079da08 commit 776bc1e
Show file tree
Hide file tree
Showing 13 changed files with 412 additions and 209 deletions.
3 changes: 3 additions & 0 deletions app/_locales/en/messages.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import Confirmation from './confirmation';
class TransactionConfirmation extends Confirmation {
private walletInitiatedHeadingTitle: RawLocator;

private dappInitiatedHeadingTitle: RawLocator;

constructor(driver: Driver) {
super(driver);

Expand All @@ -15,11 +17,19 @@ class TransactionConfirmation extends Confirmation {
css: 'h3',
text: tEn('review') as string,
};
this.dappInitiatedHeadingTitle = {
css: 'h3',
text: tEn('transferRequest') as string,
};
}

async check_walletInitiatedHeadingTitle() {
await this.driver.waitForSelector(this.walletInitiatedHeadingTitle);
}

async check_dappInitiatedHeadingTitle() {
await this.driver.waitForSelector(this.dappInitiatedHeadingTitle);
}
}

export default TransactionConfirmation;
6 changes: 6 additions & 0 deletions test/e2e/page-objects/pages/test-dapp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,8 @@ class TestDapp {
tag: 'button',
};

private erc20TokenTransferButton = '#transferTokens';

constructor(driver: Driver) {
this.driver = driver;
}
Expand Down Expand Up @@ -192,6 +194,10 @@ class TestDapp {
await this.driver.clickElement(this.erc20WatchAssetButton);
}

public async clickERC20TokenTransferButton() {
await this.driver.clickElement(this.erc20TokenTransferButton);
}

/**
* Connect account to test dapp.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
/* eslint-disable @typescript-eslint/no-require-imports, @typescript-eslint/no-var-requires */
import { TransactionEnvelopeType } from '@metamask/transaction-controller';
import { DAPP_URL } from '../../../constants';
import { unlockWallet, WINDOW_TITLES } from '../../../helpers';
import {
unlockWallet,
veryLargeDelayMs,
WINDOW_TITLES,
} from '../../../helpers';
import { Mockttp } from '../../../mock-e2e';
import WatchAssetConfirmation from '../../../page-objects/pages/confirmations/legacy/watch-asset-confirmation';
import TokenTransferTransactionConfirmation from '../../../page-objects/pages/confirmations/redesign/token-transfer-confirmation';
Expand All @@ -16,28 +20,68 @@ import { TestSuiteArguments } from './shared';
const { SMART_CONTRACTS } = require('../../../seeder/smart-contracts');

describe('Confirmation Redesign ERC20 Token Send @no-mmi', function () {
it('Sends a type 0 transaction (Legacy)', async function () {
await withRedesignConfirmationFixtures(
this.test?.fullTitle(),
TransactionEnvelopeType.legacy,
async ({ driver, contractRegistry }: TestSuiteArguments) => {
await createTransactionAndAssertDetails(driver, contractRegistry);
},
mocks,
SMART_CONTRACTS.HST,
);
describe('Wallet initiated', async function () {
it('Sends a type 0 transaction (Legacy)', async function () {
await withRedesignConfirmationFixtures(
this.test?.fullTitle(),
TransactionEnvelopeType.legacy,
async ({ driver, contractRegistry }: TestSuiteArguments) => {
await createWalletInitiatedTransactionAndAssertDetails(
driver,
contractRegistry,
);
},
mocks,
SMART_CONTRACTS.HST,
);
});

it('Sends a type 2 transaction (EIP1559)', async function () {
await withRedesignConfirmationFixtures(
this.test?.fullTitle(),
TransactionEnvelopeType.feeMarket,
async ({ driver, contractRegistry }: TestSuiteArguments) => {
await createWalletInitiatedTransactionAndAssertDetails(
driver,
contractRegistry,
);
},
mocks,
SMART_CONTRACTS.HST,
);
});
});

it('Sends a type 2 transaction (EIP1559)', async function () {
await withRedesignConfirmationFixtures(
this.test?.fullTitle(),
TransactionEnvelopeType.feeMarket,
async ({ driver, contractRegistry }: TestSuiteArguments) => {
await createTransactionAndAssertDetails(driver, contractRegistry);
},
mocks,
SMART_CONTRACTS.HST,
);
describe('dApp initiated', async function () {
it('Sends a type 0 transaction (Legacy)', async function () {
await withRedesignConfirmationFixtures(
this.test?.fullTitle(),
TransactionEnvelopeType.legacy,
async ({ driver, contractRegistry }: TestSuiteArguments) => {
await createDAppInitiatedTransactionAndAssertDetails(
driver,
contractRegistry,
);
},
mocks,
SMART_CONTRACTS.HST,
);
});

it('Sends a type 2 transaction (EIP1559)', async function () {
await withRedesignConfirmationFixtures(
this.test?.fullTitle(),
TransactionEnvelopeType.feeMarket,
async ({ driver, contractRegistry }: TestSuiteArguments) => {
await createDAppInitiatedTransactionAndAssertDetails(
driver,
contractRegistry,
);
},
mocks,
SMART_CONTRACTS.HST,
);
});
});
});

Expand Down Expand Up @@ -69,7 +113,7 @@ export async function mockedSourcifyTokenSend(mockServer: Mockttp) {
}));
}

async function createTransactionAndAssertDetails(
async function createWalletInitiatedTransactionAndAssertDetails(
driver: Driver,
contractRegistry?: GanacheContractAddressRegistry,
) {
Expand Down Expand Up @@ -113,3 +157,39 @@ async function createTransactionAndAssertDetails(

await tokenTransferTransactionConfirmation.clickFooterConfirmButton();
}

async function createDAppInitiatedTransactionAndAssertDetails(
driver: Driver,
contractRegistry?: GanacheContractAddressRegistry,
) {
await unlockWallet(driver);

const contractAddress = await (
contractRegistry as GanacheContractAddressRegistry
).getContractAddress(SMART_CONTRACTS.HST);

const testDapp = new TestDapp(driver);

await testDapp.openTestDappPage({ contractAddress, url: DAPP_URL });

await testDapp.clickERC20WatchAssetButton();

await driver.delay(veryLargeDelayMs);
await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog);
const watchAssetConfirmation = new WatchAssetConfirmation(driver);
await watchAssetConfirmation.clickFooterConfirmButton();

await driver.switchToWindowWithTitle(WINDOW_TITLES.TestDApp);
await testDapp.clickERC20TokenTransferButton();

await driver.delay(veryLargeDelayMs);
await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog);
const tokenTransferTransactionConfirmation =
new TokenTransferTransactionConfirmation(driver);
await tokenTransferTransactionConfirmation.check_dappInitiatedHeadingTitle();
await tokenTransferTransactionConfirmation.check_networkParagraph();
await tokenTransferTransactionConfirmation.check_interactingWithParagraph();
await tokenTransferTransactionConfirmation.check_networkFeeParagraph();

await tokenTransferTransactionConfirmation.clickFooterConfirmButton();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`<DAppInitiatedHeader /> should match snapshot 1`] = `
<div>
<div
class="mm-box mm-box--padding-3 mm-box--display-flex mm-box--flex-direction-row mm-box--justify-content-center mm-box--align-items-center mm-box--background-color-background-default"
style="z-index: 2; position: relative;"
>
<h3
class="mm-box mm-text mm-text--heading-md mm-box--color-inherit"
>
Transfer request
</h3>
<div
class="mm-box mm-box--padding-right-3"
style="margin-left: auto; position: absolute; right: 0px;"
>
<div
class="mm-box mm-box--margin-right-1 mm-box--background-color-transparent mm-box--rounded-md"
>
<button
aria-label="Advanced tx details"
class="mm-box mm-button-icon mm-button-icon--size-md mm-box--display-inline-flex mm-box--justify-content-center mm-box--align-items-center mm-box--color-icon-default mm-box--background-color-transparent mm-box--rounded-lg"
data-testid="header-advanced-details-button"
>
<span
class="mm-box mm-icon mm-icon--size-md mm-box--display-inline-block mm-box--color-inherit"
style="mask-image: url('./images/icons/customize.svg');"
/>
</button>
</div>
</div>
</div>
</div>
`;
Original file line number Diff line number Diff line change
Expand Up @@ -116,122 +116,31 @@ exports[`Header should match snapshot with signature confirmation 1`] = `
exports[`Header should match snapshot with token transfer confirmation initiated in a dApp 1`] = `
<div>
<div
class="mm-box confirm_header__wrapper mm-box--display-flex mm-box--justify-content-space-between mm-box--align-items-center"
data-testid="confirm-header"
class="mm-box mm-box--padding-3 mm-box--display-flex mm-box--flex-direction-row mm-box--justify-content-center mm-box--align-items-center mm-box--background-color-background-default"
style="z-index: 2; position: relative;"
>
<div
class="mm-box mm-box--padding-4 mm-box--display-flex mm-box--align-items-flex-start"
<h3
class="mm-box mm-text mm-text--heading-md mm-box--color-inherit"
>
<div
class="mm-box mm-box--margin-top-2 mm-box--display-flex"
>
<div
class=""
>
<div
class="identicon"
style="height: 32px; width: 32px; border-radius: 16px;"
>
<div
style="border-radius: 50px; overflow: hidden; padding: 0px; margin: 0px; width: 32px; height: 32px; display: inline-block; background: rgb(24, 100, 242);"
>
<svg
height="32"
width="32"
x="0"
y="0"
>
<rect
fill="#C81420"
height="32"
transform="translate(-5.505236904904678 -5.265123363737541) rotate(385.9 16 16)"
width="32"
x="0"
y="0"
/>
<rect
fill="#E9F500"
height="32"
transform="translate(10.674469406726399 12.429928159193388) rotate(184.5 16 16)"
width="32"
x="0"
y="0"
/>
<rect
fill="#FAB300"
height="32"
transform="translate(1.815455199236231 -26.03028190637629) rotate(431.3 16 16)"
width="32"
x="0"
y="0"
/>
</svg>
</div>
</div>
</div>
<div
class="mm-box mm-text mm-avatar-base mm-avatar-base--size-xs mm-avatar-network confirm_header__avatar-network mm-text--body-xs mm-text--text-transform-uppercase mm-box--display-flex mm-box--justify-content-center mm-box--align-items-center mm-box--color-text-default mm-box--background-color-goerli mm-box--rounded-full mm-box--border-color-transparent box--border-style-solid box--border-width-1"
>
G
</div>
</div>
<div
class="mm-box mm-box--margin-inline-start-4"
>
<p
class="mm-box mm-text mm-text--body-md-medium mm-box--color-text-default"
data-testid="header-account-name"
/>
<p
class="mm-box mm-text mm-text--body-md mm-box--color-text-alternative"
data-testid="header-network-display-name"
>
Goerli
</p>
</div>
</div>
Transfer request
</h3>
<div
class="mm-box mm-box--padding-4 mm-box--display-flex mm-box--align-items-flex-end"
class="mm-box mm-box--padding-right-3"
style="margin-left: auto; position: absolute; right: 0px;"
>
<div
class="mm-box mm-box--display-flex mm-box--justify-content-flex-end"
style="align-self: flex-end;"
class="mm-box mm-box--margin-right-1 mm-box--background-color-transparent mm-box--rounded-md"
>
<div>
<div
aria-describedby="tippy-tooltip-3"
class=""
data-original-title="Account details"
data-tooltipped=""
style="display: inline;"
tabindex="0"
>
<button
aria-label="Account details"
class="mm-box mm-button-icon mm-button-icon--size-md mm-box--display-inline-flex mm-box--justify-content-center mm-box--align-items-center mm-box--color-icon-default mm-box--background-color-transparent mm-box--rounded-lg"
data-testid="header-info__account-details-button"
>
<span
class="mm-box mm-icon mm-icon--size-md mm-box--display-inline-block mm-box--color-inherit"
style="mask-image: url('./images/icons/info.svg');"
/>
</button>
</div>
</div>
<div
class="mm-box mm-box--margin-right-1 mm-box--background-color-transparent mm-box--rounded-md"
<button
aria-label="Advanced tx details"
class="mm-box mm-button-icon mm-button-icon--size-md mm-box--display-inline-flex mm-box--justify-content-center mm-box--align-items-center mm-box--color-icon-default mm-box--background-color-transparent mm-box--rounded-lg"
data-testid="header-advanced-details-button"
>
<button
aria-label="Advanced tx details"
class="mm-box mm-button-icon mm-button-icon--size-md mm-box--display-inline-flex mm-box--justify-content-center mm-box--align-items-center mm-box--color-icon-default mm-box--background-color-transparent mm-box--rounded-lg"
data-testid="header-advanced-details-button"
>
<span
class="mm-box mm-icon mm-icon--size-md mm-box--display-inline-block mm-box--color-inherit"
style="mask-image: url('./images/icons/customize.svg');"
/>
</button>
</div>
<span
class="mm-box mm-icon mm-icon--size-md mm-box--display-inline-block mm-box--color-inherit"
style="mask-image: url('./images/icons/customize.svg');"
/>
</button>
</div>
</div>
</div>
Expand Down
Loading

0 comments on commit 776bc1e

Please sign in to comment.