1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-11-29 07:16:36 +01:00

Update signature request screens (#15776)

Fix e2e test

Update siteicon for v4 signature type

Code refactor

Code refactor

Remove origin and address in signatrue request

Update e2e tests

Use getNetworkName function

Move header component inline jsx

Update snaps
This commit is contained in:
amerkadicE 2022-11-30 19:11:36 +01:00 committed by GitHub
parent b3895b6840
commit 80e4a1fef4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 304 additions and 413 deletions

View File

@ -42,7 +42,7 @@ describe('Eth sign', function () {
); );
const title = await driver.findElement( const title = await driver.findElement(
'.request-signature__header__text', '.request-signature__content__title',
); );
const origin = await driver.findElement('.request-signature__origin'); const origin = await driver.findElement('.request-signature__origin');
assert.equal(await title.getText(), 'Signature request'); assert.equal(await title.getText(), 'Signature request');

View File

@ -45,23 +45,17 @@ describe('Sign Typed Data V4 Signature Request', function () {
); );
const title = await driver.findElement( const title = await driver.findElement(
'.signature-request-content__title', '.signature-request__content__title',
);
const name = await driver.findElement(
'.signature-request-content__info--bolded',
);
const content = await driver.findElements(
'.signature-request-content__info',
); );
const origin = await driver.findElement('.signature-request__origin');
const verifyContractDetailsButton = await driver.findElement( const verifyContractDetailsButton = await driver.findElement(
'.signature-request-content__verify-contract-details', '.signature-request-content__verify-contract-details',
); );
const origin = content[0];
const message = await driver.findElement( const message = await driver.findElement(
'.signature-request-data__node__value', '.signature-request-data__node__value',
); );
assert.equal(await title.getText(), 'Signature request'); assert.equal(await title.getText(), 'Signature request');
assert.equal(await name.getText(), 'Ether Mail');
assert.equal(await origin.getText(), 'http://127.0.0.1:8080'); assert.equal(await origin.getText(), 'http://127.0.0.1:8080');
verifyContractDetailsButton.click(); verifyContractDetailsButton.click();
@ -131,23 +125,18 @@ describe('Sign Typed Data V3 Signature Request', function () {
); );
const title = await driver.findElement( const title = await driver.findElement(
'.signature-request-content__title', '.signature-request__content__title',
);
const name = await driver.findElement(
'.signature-request-content__info--bolded',
);
const content = await driver.findElements(
'.signature-request-content__info',
); );
const origin = await driver.findElement('.signature-request__origin');
const verifyContractDetailsButton = await driver.findElement( const verifyContractDetailsButton = await driver.findElement(
'.signature-request-content__verify-contract-details', '.signature-request-content__verify-contract-details',
); );
const origin = content[0];
const messages = await driver.findElements( const messages = await driver.findElements(
'.signature-request-data__node__value', '.signature-request-data__node__value',
); );
assert.equal(await title.getText(), 'Signature request'); assert.equal(await title.getText(), 'Signature request');
assert.equal(await name.getText(), 'Ether Mail');
assert.equal(await origin.getText(), 'http://127.0.0.1:8080'); assert.equal(await origin.getText(), 'http://127.0.0.1:8080');
verifyContractDetailsButton.click(); verifyContractDetailsButton.click();
@ -217,7 +206,7 @@ describe('Sign Typed Data Signature Request', function () {
); );
const title = await driver.findElement( const title = await driver.findElement(
'.request-signature__header__text', '.request-signature__content__title',
); );
const origin = await driver.findElement('.request-signature__origin'); const origin = await driver.findElement('.request-signature__origin');
const message = await driver.findElements( const message = await driver.findElements(

View File

@ -4,87 +4,56 @@ exports[`SignatureRequestOriginal should match snapshot 1`] = `
<div> <div>
<div <div
class="request-signature__container" class="request-signature__container"
>
<div
class="request-signature__header"
>
<div
class="request-signature__header-background"
/>
<div
class="request-signature__header__text"
>
Signature request
</div>
<div
class="request-signature__header__tip-container"
>
<div
class="request-signature__header__tip"
/>
</div>
</div>
<div
class="request-signature__body"
>
<div
class="request-signature__account-info"
> >
<div <div
class="request-signature__account" class="request-signature__account"
> >
<div <div
class="request-signature__account-text" class="box network-account-balance-header box--padding-4 box--display-flex box--flex-direction-row box--justify-content-space-between box--align-items-center"
>
Account:
</div>
<div
class="request-signature__account-item"
> >
<div <div
class="account-list-item undefined" class="box box--display-flex box--gap-2 box--flex-direction-row box--align-items-center"
data-testid="account-list-item"
> >
<div <div
class="account-list-item__top-row" class="box box--display-flex box--flex-direction-row box--align-items-center"
> >
<div <div
class="" class=""
> >
<div <div
class="identicon account-list-item__identicon" class="identicon"
style="height: 18px; width: 18px; border-radius: 9px;" style="height: 32px; width: 32px; border-radius: 16px;"
> >
<div <div
style="border-radius: 50px; overflow: hidden; padding: 0px; margin: 0px; width: 18px; height: 18px; display: inline-block; background: rgb(250, 58, 0);" style="border-radius: 50px; overflow: hidden; padding: 0px; margin: 0px; width: 32px; height: 32px; display: inline-block; background: rgb(250, 58, 0);"
> >
<svg <svg
height="18" height="32"
width="18" width="32"
x="0" x="0"
y="0" y="0"
> >
<rect <rect
fill="#18CDF2" fill="#18CDF2"
height="18" height="32"
transform="translate(-0.5897213458840913 -1.8586597890715306) rotate(328.9 9 9)" transform="translate(-1.04839350379394 -3.3042840694604987) rotate(328.9 16 16)"
width="18" width="32"
x="0" x="0"
y="0" y="0"
/> />
<rect <rect
fill="#035E56" fill="#035E56"
height="18" height="32"
transform="translate(-10.292884711218024 5.9582598028585885) rotate(176.2 9 9)" transform="translate(-18.298461708832043 10.5924618717486) rotate(176.2 16 16)"
width="18" width="32"
x="0" x="0"
y="0" y="0"
/> />
<rect <rect
fill="#F26602" fill="#F26602"
height="18" height="32"
transform="translate(9.375661135250958 -7.990391094185859) rotate(468.9 9 9)" transform="translate(16.667842018223922 -14.205139722997082) rotate(468.9 16 16)"
width="18" width="32"
x="0" x="0"
y="0" y="0"
/> />
@ -93,55 +62,84 @@ exports[`SignatureRequestOriginal should match snapshot 1`] = `
</div> </div>
</div> </div>
<div <div
class="account-list-item__account-name" class="network-account-balance-header__network-account__ident-icon-ethereum--gray"
>
<span
class="icon-with-fallback__fallback"
>
U
</span>
</div>
</div>
<div
class="box box--display-flex box--flex-direction-column box--align-items-flex-start"
>
<h6
class="box box--margin-top-1 box--flex-direction-row typography typography--h6 typography--weight-normal typography--style-normal typography--color-text-alternative"
>
Unknown private network
</h6>
<h6
class="box box--margin-bottom-1 box--flex-direction-row typography typography--h6 typography--weight-bold typography--style-normal typography--color-text-default"
> >
Test Account Test Account
</h6>
</div> </div>
</div> </div>
<div
class="box box--display-flex box--flex-direction-column box--align-items-flex-end"
>
<h6
class="box box--margin-top-1 box--flex-direction-row typography typography--h6 typography--weight-normal typography--style-normal typography--color-text-alternative"
>
Balance
</h6>
<h6
class="box box--margin-bottom-1 box--flex-direction-row typography typography--h6 typography--weight-bold typography--style-normal typography--align-end typography--color-text-default"
>
0
ETH
</h6>
</div> </div>
</div> </div>
</div> </div>
<div <div
class="request-signature__request-icon" class="request-signature__body"
> >
<div <div
class="identicon__image-border" class="request-signature__origin"
style="height: 40px; width: 40px; border-radius: 20px;" >
<div
class="site-origin"
>
<div
class="chip chip--with-left-icon chip--border-color-border-muted chip--background-color-undefined"
>
<div
class="chip__left-icon"
>
<div
class=""
>
<span
class="icon-with-fallback__fallback"
/> />
</div> </div>
<div
class="request-signature__balance"
>
<div
class="request-signature__balance-text"
>
Balance:
</div> </div>
<div <span
class="request-signature__balance-value" class="box box--margin-top-1 box--margin-bottom-1 box--flex-direction-row typography chip__label typography--h6 typography--weight-normal typography--style-normal typography--color-text-alternative"
>
0 ETH
</div>
</div>
</div>
<div
class="request-signature__origin-row"
>
<div
class="request-signature__origin-label"
>
Origin:
</div>
<div
class="site-origin request-signature__origin"
>
<bdi
dir="ltr"
> >
https://happydapp.website/governance?futarchy=true https://happydapp.website/governance?futarchy=true
</bdi> </span>
</div> </div>
</div> </div>
</div>
<h3
class="box box--margin-top-1 box--margin-bottom-1 box--flex-direction-row typography request-signature__content__title typography--h3 typography--weight-bold typography--style-normal typography--color-text-default"
>
Signature request
</h3>
<div <div
class="request-signature__notice" class="request-signature__notice"
> >

View File

@ -45,106 +45,17 @@
} }
} }
&__header { &__content__title {
height: 64px;
width: 100%;
position: relative;
display: flex;
flex-flow: column;
justify-content: center;
align-items: center;
flex: 0 0 auto;
}
&__header-background {
position: absolute;
background-color: var(--color-background-alternative);
z-index: 2;
width: 100%;
height: 100%;
}
&__header__text {
@include H3; @include H3;
display: flex;
justify-content: center;
color: var(--color-default-text); color: var(--color-default-text);
z-index: 3; z-index: 3;
} }
&__header__tip-container {
width: 100%;
display: flex;
justify-content: center;
}
&__header__tip {
height: 25px;
width: 25px;
background: var(--color-background-alternative);
transform: rotate(45deg);
position: absolute;
bottom: -8px;
z-index: 1;
}
&__account-info {
display: flex;
justify-content: space-between;
margin-top: 18px;
margin-bottom: 20px;
}
&__account { &__account {
color: var(--color-text-alternative); width: 100%;
margin-left: 17px;
}
&__account-text {
@include H6;
}
&__account-item {
@include H7;
height: 22px;
background-color: var(--color-background-default);
width: 124px;
.account-list-item {
margin-top: 6px;
}
.account-list-item__account-name {
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
width: 80px;
}
.account-list-item__top-row {
margin: 0;
}
}
&__balance {
color: var(--color-text-alternative);
margin-right: 17px;
width: 124px;
}
&__balance-text {
@include H6;
text-align: right;
}
&__balance-value {
text-align: right;
margin-top: 2.5px;
}
&__request-icon {
margin-top: 25px;
} }
&__body { &__body {
@ -155,24 +66,11 @@
flex: 1 1 auto; flex: 1 1 auto;
} }
&__origin-row {
@include Paragraph;
display: flex;
margin: 0 15px;
}
&__origin-label {
flex-grow: 1;
margin-right: 5px;
}
&__origin-icon {
flex: 0 0 24px;
}
&__origin { &__origin {
margin-left: 5px; display: flex;
justify-content: center;
margin-top: 16px;
margin-bottom: 16px;
} }
&__notice, &__notice,

View File

@ -7,13 +7,17 @@ import LedgerInstructionField from '../ledger-instruction-field';
import { MESSAGE_TYPE } from '../../../../shared/constants/app'; import { MESSAGE_TYPE } from '../../../../shared/constants/app';
import { EVENT } from '../../../../shared/constants/metametrics'; import { EVENT } from '../../../../shared/constants/metametrics';
import { getURLHostName } from '../../../helpers/utils/util'; import { getURLHostName } from '../../../helpers/utils/util';
import Identicon from '../../ui/identicon';
import AccountListItem from '../account-list-item';
import { conversionUtil } from '../../../../shared/modules/conversion.utils'; import { conversionUtil } from '../../../../shared/modules/conversion.utils';
import { stripHexPrefix } from '../../../../shared/modules/hexstring-utils'; import { stripHexPrefix } from '../../../../shared/modules/hexstring-utils';
import Button from '../../ui/button'; import Button from '../../ui/button';
import SiteIcon from '../../ui/site-icon';
import SiteOrigin from '../../ui/site-origin'; import SiteOrigin from '../../ui/site-origin';
import NetworkAccountBalanceHeader from '../network-account-balance-header';
import Typography from '../../ui/typography/typography';
import {
TYPOGRAPHY,
FONT_WEIGHT,
} from '../../../helpers/constants/design-system';
import { NETWORK_TYPES } from '../../../../shared/constants/network';
import SignatureRequestOriginalWarning from './signature-request-original-warning'; import SignatureRequestOriginalWarning from './signature-request-original-warning';
export default class SignatureRequestOriginal extends Component { export default class SignatureRequestOriginal extends Component {
@ -33,7 +37,6 @@ export default class SignatureRequestOriginal extends Component {
conversionRate: PropTypes.number, conversionRate: PropTypes.number,
history: PropTypes.object.isRequired, history: PropTypes.object.isRequired,
mostRecentOverviewPage: PropTypes.string.isRequired, mostRecentOverviewPage: PropTypes.string.isRequired,
requesterAddress: PropTypes.string,
sign: PropTypes.func.isRequired, sign: PropTypes.func.isRequired,
txData: PropTypes.object.isRequired, txData: PropTypes.object.isRequired,
subjectMetadata: PropTypes.object, subjectMetadata: PropTypes.object,
@ -43,6 +46,7 @@ export default class SignatureRequestOriginal extends Component {
messagesCount: PropTypes.number, messagesCount: PropTypes.number,
showRejectTransactionsConfirmationModal: PropTypes.func.isRequired, showRejectTransactionsConfirmationModal: PropTypes.func.isRequired,
cancelAll: PropTypes.func.isRequired, cancelAll: PropTypes.func.isRequired,
provider: PropTypes.object,
}; };
state = { state = {
@ -50,115 +54,24 @@ export default class SignatureRequestOriginal extends Component {
showSignatureRequestWarning: false, showSignatureRequestWarning: false,
}; };
renderHeader = () => { getNetworkName() {
return ( const { provider } = this.props;
<div className="request-signature__header"> const providerName = provider.type;
<div className="request-signature__header-background" />
<div className="request-signature__header__text">
{this.context.t('sigRequest')}
</div>
<div className="request-signature__header__tip-container">
<div className="request-signature__header__tip" />
</div>
</div>
);
};
renderAccount = () => {
const { fromAccount } = this.state;
return (
<div className="request-signature__account">
<div className="request-signature__account-text">
{`${this.context.t('account')}:`}
</div>
<div className="request-signature__account-item">
<AccountListItem account={fromAccount} />
</div>
</div>
);
};
renderBalance = () => {
const { conversionRate, nativeCurrency } = this.props;
const {
fromAccount: { balance },
} = this.state;
const balanceInBaseAsset = conversionUtil(balance, {
fromNumericBase: 'hex',
toNumericBase: 'dec',
fromDenomination: 'WEI',
numberOfDecimals: 6,
conversionRate,
});
return (
<div className="request-signature__balance">
<div className="request-signature__balance-text">
{`${this.context.t('balance')}:`}
</div>
<div className="request-signature__balance-value">
{`${balanceInBaseAsset} ${nativeCurrency}`}
</div>
</div>
);
};
renderRequestIcon = () => {
const { requesterAddress } = this.props;
return (
<div className="request-signature__request-icon">
<Identicon diameter={40} address={requesterAddress} />
</div>
);
};
renderAccountInfo = () => {
return (
<div className="request-signature__account-info">
{this.renderAccount()}
{this.renderRequestIcon()}
{this.renderBalance()}
</div>
);
};
renderOriginInfo = () => {
const { txData, subjectMetadata } = this.props;
const { t } = this.context; const { t } = this.context;
const targetSubjectMetadata = txData.msgParams.origin switch (providerName) {
? subjectMetadata?.[txData.msgParams.origin] case NETWORK_TYPES.MAINNET:
: null; return t('mainnet');
case NETWORK_TYPES.GOERLI:
return ( return t('goerli');
<div className="request-signature__origin-row"> case NETWORK_TYPES.SEPOLIA:
<div className="request-signature__origin-label"> return t('sepolia');
{`${t('origin')}:`} case NETWORK_TYPES.LOCALHOST:
</div> return t('localhost');
{targetSubjectMetadata?.iconUrl ? ( default:
<SiteIcon return provider.nickname || t('unknownNetwork');
className="request-signature__origin-icon" }
icon={targetSubjectMetadata.iconUrl}
name={
getURLHostName(targetSubjectMetadata.origin) ||
targetSubjectMetadata.origin
} }
size={24}
/>
) : null}
<SiteOrigin
className="request-signature__origin"
siteOrigin={txData.msgParams.origin}
/>
</div>
);
};
msgHexToText = (hex) => { msgHexToText = (hex) => {
try { try {
@ -199,7 +112,7 @@ export default class SignatureRequestOriginal extends Component {
let rows; let rows;
const notice = `${this.context.t('youSign')}:`; const notice = `${this.context.t('youSign')}:`;
const { txData } = this.props; const { txData, subjectMetadata } = this.props;
const { const {
type, type,
msgParams: { data }, msgParams: { data },
@ -215,10 +128,32 @@ export default class SignatureRequestOriginal extends Component {
rows = [{ name: this.context.t('message'), value: data }]; rows = [{ name: this.context.t('message'), value: data }];
} }
const targetSubjectMetadata = txData.msgParams.origin
? subjectMetadata?.[txData.msgParams.origin]
: null;
return ( return (
<div className="request-signature__body"> <div className="request-signature__body">
{this.renderAccountInfo()} <div className="request-signature__origin">
{this.renderOriginInfo()} <SiteOrigin
siteOrigin={txData.msgParams.origin}
iconSrc={targetSubjectMetadata?.iconUrl}
iconName={
getURLHostName(targetSubjectMetadata?.origin) ||
targetSubjectMetadata?.origin
}
chip
/>
</div>
<Typography
className="request-signature__content__title"
variant={TYPOGRAPHY.H3}
fontWeight={FONT_WEIGHT.BOLD}
>
{this.context.t('sigRequest')}
</Typography>
<div className={classnames('request-signature__notice')}>{notice}</div> <div className={classnames('request-signature__notice')}>{notice}</div>
<div className="request-signature__rows"> <div className="request-signature__rows">
{rows.map(({ name, value }, index) => { {rows.map(({ name, value }, index) => {
@ -367,13 +302,32 @@ export default class SignatureRequestOriginal extends Component {
}; };
render = () => { render = () => {
const { messagesCount } = this.props; const { messagesCount, conversionRate, nativeCurrency } = this.props;
const { showSignatureRequestWarning, fromAccount } = this.state; const { fromAccount, showSignatureRequestWarning } = this.state;
const { t } = this.context; const { t } = this.context;
const rejectNText = t('rejectRequestsN', [messagesCount]); const rejectNText = t('rejectRequestsN', [messagesCount]);
const currentNetwork = this.getNetworkName();
const balanceInBaseAsset = conversionUtil(fromAccount.balance, {
fromNumericBase: 'hex',
toNumericBase: 'dec',
fromDenomination: 'WEI',
numberOfDecimals: 6,
conversionRate,
});
return ( return (
<div className="request-signature__container"> <div className="request-signature__container">
{this.renderHeader()} <div className="request-signature__account">
<NetworkAccountBalanceHeader
networkName={currentNetwork}
accountName={fromAccount.name}
accountBalance={balanceInBaseAsset}
tokenName={nativeCurrency}
accountAddress={fromAccount.address}
/>
</div>
{this.renderBody()} {this.renderBody()}
{this.props.isLedgerWallet ? ( {this.props.isLedgerWallet ? (
<div className="confirm-approve-content__ledger-instruction-wrapper"> <div className="confirm-approve-content__ledger-instruction-wrapper">

View File

@ -25,13 +25,13 @@ function mapStateToProps(state, ownProps) {
const { const {
msgParams: { from }, msgParams: { from },
} = ownProps.txData; } = ownProps.txData;
const { provider } = state.metamask;
const hardwareWalletRequiresConnection = const hardwareWalletRequiresConnection =
doesAddressRequireLedgerHidConnection(state, from); doesAddressRequireLedgerHidConnection(state, from);
const isLedgerWallet = isAddressLedger(state, from); const isLedgerWallet = isAddressLedger(state, from);
const messagesList = unconfirmedMessagesHashSelector(state); const messagesList = unconfirmedMessagesHashSelector(state);
const messagesCount = getTotalUnapprovedMessagesCount(state); const messagesCount = getTotalUnapprovedMessagesCount(state);
return { return {
requester: null, requester: null,
requesterAddress: null, requesterAddress: null,
@ -45,6 +45,7 @@ function mapStateToProps(state, ownProps) {
subjectMetadata: getSubjectMetadata(state), subjectMetadata: getSubjectMetadata(state),
messagesList, messagesList,
messagesCount, messagesCount,
provider,
}; };
} }

View File

@ -38,34 +38,6 @@
font-weight: 500; font-weight: 500;
} }
&__identicon-container {
padding: 1rem;
flex: 1;
position: relative;
width: 100%;
display: flex;
justify-content: center;
align-items: center;
}
&__identicon-border {
height: 75px;
width: 75px;
border-radius: 50%;
border: 1px solid var(--color-background-default);
position: absolute;
}
&__identicon-initial {
position: absolute;
font-style: normal;
font-weight: 500;
font-size: 60px;
color: var(--color-background-default);
z-index: 1;
text-shadow: var(--shadow-size-xs) var(--color-shadow-default);
}
&__info { &__info {
@include H7; @include H7;

View File

@ -1,17 +1,22 @@
import React, { PureComponent } from 'react'; import React, { PureComponent } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import Identicon from '../../ui/identicon';
import LedgerInstructionField from '../ledger-instruction-field'; import LedgerInstructionField from '../ledger-instruction-field';
import { sanitizeMessage } from '../../../helpers/utils/util'; import { sanitizeMessage, getURLHostName } from '../../../helpers/utils/util';
import { EVENT } from '../../../../shared/constants/metametrics'; import { EVENT } from '../../../../shared/constants/metametrics';
import { conversionUtil } from '../../../../shared/modules/conversion.utils';
import SiteOrigin from '../../ui/site-origin'; import SiteOrigin from '../../ui/site-origin';
import Button from '../../ui/button'; import Button from '../../ui/button';
import Typography from '../../ui/typography/typography'; import Typography from '../../ui/typography/typography';
import { COLORS, TYPOGRAPHY } from '../../../helpers/constants/design-system';
import ContractDetailsModal from '../modals/contract-details-modal/contract-details-modal'; import ContractDetailsModal from '../modals/contract-details-modal/contract-details-modal';
import Message from './signature-request-message'; import {
TYPOGRAPHY,
FONT_WEIGHT,
COLORS,
} from '../../../helpers/constants/design-system';
import NetworkAccountBalanceHeader from '../network-account-balance-header';
import { NETWORK_TYPES } from '../../../../shared/constants/network';
import Footer from './signature-request-footer'; import Footer from './signature-request-footer';
import Header from './signature-request-header'; import Message from './signature-request-message';
export default class SignatureRequest extends PureComponent { export default class SignatureRequest extends PureComponent {
static propTypes = { static propTypes = {
@ -55,6 +60,10 @@ export default class SignatureRequest extends PureComponent {
* Dapp image * Dapp image
*/ */
siteImage: PropTypes.string, siteImage: PropTypes.string,
conversionRate: PropTypes.number,
nativeCurrency: PropTypes.string,
provider: PropTypes.object,
subjectMetadata: PropTypes.object,
}; };
static contextTypes = { static contextTypes = {
@ -78,13 +87,32 @@ export default class SignatureRequest extends PureComponent {
)}`; )}`;
} }
getNetworkName() {
const { provider } = this.props;
const providerName = provider.type;
const { t } = this.context;
switch (providerName) {
case NETWORK_TYPES.MAINNET:
return t('mainnet');
case NETWORK_TYPES.GOERLI:
return t('goerli');
case NETWORK_TYPES.SEPOLIA:
return t('sepolia');
case NETWORK_TYPES.LOCALHOST:
return t('localhost');
default:
return provider.nickname || t('unknownNetwork');
}
}
render() { render() {
const { const {
fromAccount,
txData: { txData: {
msgParams: { data, origin, version }, msgParams: { data, origin, version },
type, type,
}, },
fromAccount: { address, balance, name },
cancel, cancel,
sign, sign,
isLedgerWallet, isLedgerWallet,
@ -92,11 +120,24 @@ export default class SignatureRequest extends PureComponent {
chainId, chainId,
rpcPrefs, rpcPrefs,
siteImage, siteImage,
txData,
subjectMetadata,
conversionRate,
nativeCurrency,
} = this.props; } = this.props;
const { address: fromAddress } = fromAccount;
const { message, domain = {}, primaryType, types } = JSON.parse(data); const { message, domain = {}, primaryType, types } = JSON.parse(data);
const { trackEvent } = this.context; const { trackEvent } = this.context;
const currentNetwork = this.getNetworkName();
const balanceInBaseAsset = conversionUtil(balance, {
fromNumericBase: 'hex',
toNumericBase: 'dec',
fromDenomination: 'WEI',
numberOfDecimals: 6,
conversionRate,
});
const onSign = (event) => { const onSign = (event) => {
sign(event); sign(event);
trackEvent({ trackEvent({
@ -128,27 +169,42 @@ export default class SignatureRequest extends PureComponent {
const messageIsScrollable = const messageIsScrollable =
this.messageRootRef?.scrollHeight > this.messageRootRef?.clientHeight; this.messageRootRef?.scrollHeight > this.messageRootRef?.clientHeight;
const targetSubjectMetadata = txData.msgParams.origin
? subjectMetadata?.[txData.msgParams.origin]
: null;
return ( return (
<div className="signature-request page-container"> <div className="signature-request page-container">
<Header fromAccount={fromAccount} /> <div className="request-signature__account">
<div className="signature-request-content"> <NetworkAccountBalanceHeader
<div className="signature-request-content__title"> networkName={currentNetwork}
{this.context.t('sigRequest')} accountName={name}
</div> accountBalance={balanceInBaseAsset}
<div className="signature-request-content__identicon-container"> tokenName={nativeCurrency}
<div className="signature-request-content__identicon-initial"> accountAddress={address}
{domain.name && domain.name[0]}
</div>
<div className="signature-request-content__identicon-border" />
<Identicon address={fromAddress} diameter={70} />
</div>
<div className="signature-request-content__info--bolded">
{domain.name}
</div>
<SiteOrigin
className="signature-request-content__info"
siteOrigin={origin}
/> />
</div>
<div className="signature-request-content">
<div className="signature-request__origin">
<SiteOrigin
siteOrigin={origin}
iconSrc={targetSubjectMetadata?.iconUrl}
iconName={getURLHostName(origin) || origin}
chip
/>
</div>
<Typography
className="signature-request__content__title"
variant={TYPOGRAPHY.H3}
fontWeight={FONT_WEIGHT.BOLD}
boxProps={{
marginTop: 4,
}}
>
{this.context.t('sigRequest')}
</Typography>
<div> <div>
<Button <Button
type="link" type="link"

View File

@ -74,6 +74,7 @@ describe('Signature Request Component', () => {
msgParams, msgParams,
}} }}
fromAccount={{ address: fromAddress }} fromAccount={{ address: fromAddress }}
provider={{ type: 'rpc' }}
/>, />,
); );
@ -113,6 +114,7 @@ describe('Signature Request Component', () => {
msgParams, msgParams,
}} }}
fromAccount={{ address: fromAddress }} fromAccount={{ address: fromAddress }}
provider={{ type: 'rpc' }}
/>, />,
); );

View File

@ -4,9 +4,13 @@ import {
doesAddressRequireLedgerHidConnection, doesAddressRequireLedgerHidConnection,
getCurrentChainId, getCurrentChainId,
getRpcPrefsForCurrentProvider, getRpcPrefsForCurrentProvider,
conversionRateSelector,
getSubjectMetadata, getSubjectMetadata,
} from '../../../selectors'; } from '../../../selectors';
import { isAddressLedger } from '../../../ducks/metamask/metamask'; import {
isAddressLedger,
getNativeCurrency,
} from '../../../ducks/metamask/metamask';
import { getAccountByAddress } from '../../../helpers/utils/util'; import { getAccountByAddress } from '../../../helpers/utils/util';
import { MESSAGE_TYPE } from '../../../../shared/constants/app'; import { MESSAGE_TYPE } from '../../../../shared/constants/app';
import SignatureRequest from './signature-request.component'; import SignatureRequest from './signature-request.component';
@ -16,6 +20,8 @@ function mapStateToProps(state, ownProps) {
const { const {
msgParams: { from }, msgParams: { from },
} = txData; } = txData;
const { provider } = state.metamask;
const hardwareWalletRequiresConnection = const hardwareWalletRequiresConnection =
doesAddressRequireLedgerHidConnection(state, from); doesAddressRequireLedgerHidConnection(state, from);
const isLedgerWallet = isAddressLedger(state, from); const isLedgerWallet = isAddressLedger(state, from);
@ -27,11 +33,15 @@ function mapStateToProps(state, ownProps) {
subjectMetadata[txData.msgParams.origin] || {}; subjectMetadata[txData.msgParams.origin] || {};
return { return {
provider,
isLedgerWallet, isLedgerWallet,
hardwareWalletRequiresConnection, hardwareWalletRequiresConnection,
chainId, chainId,
rpcPrefs, rpcPrefs,
siteImage, siteImage,
conversionRate: conversionRateSelector(state),
nativeCurrency: getNativeCurrency(state),
subjectMetadata: getSubjectMetadata(state),
// not forwarded to component // not forwarded to component
allAccounts: accountsWithSendEtherInfoSelector(state), allAccounts: accountsWithSendEtherInfoSelector(state),
}; };
@ -45,6 +55,10 @@ function mergeProps(stateProps, dispatchProps, ownProps) {
chainId, chainId,
rpcPrefs, rpcPrefs,
siteImage, siteImage,
conversionRate,
nativeCurrency,
provider,
subjectMetadata,
} = stateProps; } = stateProps;
const { const {
signPersonalMessage, signPersonalMessage,
@ -89,6 +103,10 @@ function mergeProps(stateProps, dispatchProps, ownProps) {
chainId, chainId,
rpcPrefs, rpcPrefs,
siteImage, siteImage,
conversionRate,
nativeCurrency,
provider,
subjectMetadata,
}; };
} }

View File

@ -74,6 +74,9 @@ describe('Signature Request', () => {
clearConfirmTransaction: sinon.spy(), clearConfirmTransaction: sinon.spy(),
cancelMessage: sinon.spy(), cancelMessage: sinon.spy(),
cancel: sinon.stub().resolves(), cancel: sinon.stub().resolves(),
provider: {
type: 'rpc',
},
sign: sinon.stub().resolves(), sign: sinon.stub().resolves(),
txData: { txData: {
msgParams: { msgParams: {