Skip to content

Commit

Permalink
feat: dapp initiated token transfer
Browse files Browse the repository at this point in the history
  • Loading branch information
pedronfigueiredo committed Oct 16, 2024
1 parent 181634e commit e466d09
Show file tree
Hide file tree
Showing 9 changed files with 230 additions and 21 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;
7 changes: 7 additions & 0 deletions test/e2e/page-objects/pages/test-dapp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ class TestDapp {

private erc20WatchAssetButton: RawLocator;

private erc20TokenTransferButton: RawLocator;

constructor(driver: Driver) {
this.driver = driver;

Expand All @@ -94,6 +96,7 @@ class TestDapp {
this.erc721RevokeSetApprovalForAllButton = '#revokeButton';
this.erc1155RevokeSetApprovalForAllButton = '#revokeERC1155Button';
this.erc20WatchAssetButton = '#watchAssets';
this.erc20TokenTransferButton = '#transferTokens';
}

async check_pageIsLoaded(): Promise<void> {
Expand Down Expand Up @@ -156,6 +159,10 @@ class TestDapp {
await this.driver.clickElement(this.erc20WatchAssetButton);
}

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

/**
* Verify the failed personal sign signature.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,36 +17,76 @@ 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,
);
});
});
});

async function mocks(server: Mockttp) {
return [await mocked4BytesSetApprovalForAll(server)];
}

async function createTransactionAndAssertDetails(
async function createWalletInitiatedTransactionAndAssertDetails(
driver: Driver,
contractRegistry?: GanacheContractAddressRegistry,
) {
Expand Down Expand Up @@ -90,3 +130,37 @@ 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.open({ contractAddress, url: DAPP_URL });

await testDapp.clickERC20WatchAssetButton();

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.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
@@ -0,0 +1,21 @@
import React from 'react';
import { DefaultRootState } from 'react-redux';
import { getMockTokenTransferConfirmState } from '../../../../../../test/data/confirmations/helper';
import { renderWithConfirmContextProvider } from '../../../../../../test/lib/confirmations/render-helpers';
import configureStore from '../../../../../store/store';
import { DAppInitiatedHeader } from './dapp-initiated-header';

const render = (
state: DefaultRootState = getMockTokenTransferConfirmState({}),
) => {
const store = configureStore(state);
return renderWithConfirmContextProvider(<DAppInitiatedHeader />, store);
};

describe('<DAppInitiatedHeader />', () => {
it('should match snapshot', () => {
const { container } = render();

expect(container).toMatchSnapshot();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import React from 'react';
import { Box, Text } from '../../../../../components/component-library';
import {
AlignItems,
BackgroundColor,
Display,
FlexDirection,
JustifyContent,
TextColor,
TextVariant,
} from '../../../../../helpers/constants/design-system';
import { useI18nContext } from '../../../../../hooks/useI18nContext';
import { AdvancedDetailsButton } from './advanced-details-button';

export const DAppInitiatedHeader = () => {
const t = useI18nContext();

return (
<Box
display={Display.Flex}
flexDirection={FlexDirection.Row}
justifyContent={JustifyContent.center}
alignItems={AlignItems.center}
backgroundColor={BackgroundColor.backgroundDefault}
padding={3}
style={{ zIndex: 2, position: 'relative' }}
>
<Text variant={TextVariant.headingMd} color={TextColor.inherit}>
{t('transferRequest')}
</Text>
<Box
paddingRight={3}
style={{ marginLeft: 'auto', position: 'absolute', right: 0 }}
>
<AdvancedDetailsButton />
</Box>
</Box>
);
};
2 changes: 2 additions & 0 deletions ui/pages/confirmations/components/confirm/header/header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { useConfirmContext } from '../../../context/confirm';
import useConfirmationNetworkInfo from '../../../hooks/useConfirmationNetworkInfo';
import useConfirmationRecipientInfo from '../../../hooks/useConfirmationRecipientInfo';
import { Confirmation } from '../../../types/confirm';
import { DAppInitiatedHeader } from './dapp-initiated-header';
import HeaderInfo from './header-info';
import { WalletInitiatedHeader } from './wallet-initiated-header';

Expand All @@ -39,6 +40,7 @@ const Header = () => {
if (isWalletInitiated) {
return <WalletInitiatedHeader />;
}
return <DAppInitiatedHeader />;
}

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,30 @@ import { GasFeesSection } from '../shared/gas-fees-section/gas-fees-section';
import SendHeading from '../shared/send-heading/send-heading';
import { TokenDetailsSection } from './token-details-section';
import { TransactionFlowSection } from './transaction-flow-section';
import { ConfirmInfoSection } from '../../../../../../components/app/confirm/info/row/section';
import { SimulationDetails } from '../../../simulation-details';
import { useConfirmContext } from '../../../../context/confirm';
import { TransactionMeta } from '@metamask/transaction-controller';

const TokenTransferInfo = () => {
const { currentConfirmation: transactionMeta } =
useConfirmContext<TransactionMeta>();

const isWalletInitiated = transactionMeta.origin === 'metamask';

return (
<>
<SendHeading />
<TransactionFlowSection />
{!isWalletInitiated && (
<ConfirmInfoSection noPadding>
<SimulationDetails
simulationData={transactionMeta.simulationData}
transactionId={transactionMeta.id}
isTransactionsRedesign
/>
</ConfirmInfoSection>
)}
<TokenDetailsSection />
<GasFeesSection />
<AdvancedDetails />
Expand Down

0 comments on commit e466d09

Please sign in to comment.