diff --git a/shared/constants/labels.js b/shared/constants/labels.js
new file mode 100644
index 000000000..ab03c4eb0
--- /dev/null
+++ b/shared/constants/labels.js
@@ -0,0 +1,10 @@
+// The character limit on ENS names, nicknames and addresses before we truncate
+export const TRUNCATED_NAME_CHAR_LIMIT = 11;
+
+// The number of characters to slice from the beginning of an address for truncated format:
+// `${TRUNCATED_ADDRESS_START_CHARS}...${TRUNCATED_ADDRESS_END_CHARS}`
+export const TRUNCATED_ADDRESS_START_CHARS = 5;
+
+// The number of characters to slice from the end of an address for truncated format:
+// `${TRUNCATED_ADDRESS_START_CHARS}...${TRUNCATED_ADDRESS_END_CHARS}`
+export const TRUNCATED_ADDRESS_END_CHARS = 4;
diff --git a/test/e2e/tests/from-import-ui.spec.js b/test/e2e/tests/from-import-ui.spec.js
index a7fba5982..ad97bb257 100644
--- a/test/e2e/tests/from-import-ui.spec.js
+++ b/test/e2e/tests/from-import-ui.spec.js
@@ -76,8 +76,9 @@ describe('Metamask Import UI', function () {
// shows a QR code for the account
const detailsModal = await driver.findVisibleElement('span .modal');
// shows the correct account address
- const [address] = await driver.findElements('.readonly-input__input');
- assert.equal(await address.getAttribute('value'), testAddress);
+ const address = await driver.findElement('.qr-code__address');
+
+ assert.equal(await address.getText(), testAddress);
await driver.clickElement('.account-modal__close');
await detailsModal.waitForElementState('hidden');
diff --git a/test/e2e/tests/incremental-security.spec.js b/test/e2e/tests/incremental-security.spec.js
index f6e5e5066..e000e9817 100644
--- a/test/e2e/tests/incremental-security.spec.js
+++ b/test/e2e/tests/incremental-security.spec.js
@@ -80,8 +80,8 @@ describe('Incremental Security', function () {
);
// gets the current accounts address
- const addressInput = await driver.findElement('.readonly-input__input');
- const publicAddress = await addressInput.getAttribute('value');
+ const address = await driver.findElement('.qr-code__address');
+ const publicAddress = await address.getText();
// wait for account modal to be visible
const accountModal = await driver.findVisibleElement('span .modal');
diff --git a/ui/components/app/modals/account-modal-container/index.scss b/ui/components/app/modals/account-modal-container/index.scss
index bfb0c37a8..149a4de96 100644
--- a/ui/components/app/modals/account-modal-container/index.scss
+++ b/ui/components/app/modals/account-modal-container/index.scss
@@ -31,7 +31,7 @@
@include H1;
background-color: transparent;
- color: $dusty-gray;
+ color: $ui-black;
position: absolute;
cursor: pointer;
top: -10px;
diff --git a/ui/components/app/permission-page-container/permission-page-container-content/permission-page-container-content.component.js b/ui/components/app/permission-page-container/permission-page-container-content/permission-page-container-content.component.js
index 3213e896b..7cacc40c8 100644
--- a/ui/components/app/permission-page-container/permission-page-container-content/permission-page-container-content.component.js
+++ b/ui/components/app/permission-page-container/permission-page-container-content/permission-page-container-content.component.js
@@ -70,12 +70,6 @@ export default class PermissionPageContainerContent extends PureComponent {
);
}
- getAccountDescriptor(identity) {
- return `${identity.label} (...${identity.address.slice(
- identity.address.length - 4,
- )})`;
- }
-
renderAccountTooltip(textContent) {
const { selectedIdentities } = this.props;
const { t } = this.context;
@@ -90,7 +84,7 @@ export default class PermissionPageContainerContent extends PureComponent {
{selectedIdentities.slice(0, 6).map((identity, index) => {
return (
- {this.getAccountDescriptor(identity)}
+ {identity.addressLabel}
);
})}
@@ -126,7 +120,7 @@ export default class PermissionPageContainerContent extends PureComponent {
),
]);
}
- return t('connectTo', [this.getAccountDescriptor(selectedIdentities[0])]);
+ return t('connectTo', [selectedIdentities[0]?.addressLabel]);
}
render() {
diff --git a/ui/components/app/selected-account/selected-account-component.test.js b/ui/components/app/selected-account/selected-account-component.test.js
index d50bd34f2..bc55c7e7e 100644
--- a/ui/components/app/selected-account/selected-account-component.test.js
+++ b/ui/components/app/selected-account/selected-account-component.test.js
@@ -15,7 +15,7 @@ describe('SelectedAccount Component', () => {
);
// Checksummed version of address is displayed
expect(wrapper.find('.selected-account__address').text()).toStrictEqual(
- '0x1B82...5C9D',
+ '0x1B8...5C9D',
);
expect(wrapper.find('.selected-account__name').text()).toStrictEqual(
'testName',
diff --git a/ui/components/ui/qr-code/index.scss b/ui/components/ui/qr-code/index.scss
index 521075f64..c228ffeda 100644
--- a/ui/components/ui/qr-code/index.scss
+++ b/ui/components/ui/qr-code/index.scss
@@ -24,4 +24,11 @@
color: #f7861c;
margin-bottom: 9px;
}
+
+ &__address {
+ @include H7;
+
+ background-color: $ui-1;
+ padding: 12px;
+ }
}
diff --git a/ui/components/ui/qr-code/qr-code.js b/ui/components/ui/qr-code/qr-code.js
index db0eeed2c..84f40836b 100644
--- a/ui/components/ui/qr-code/qr-code.js
+++ b/ui/components/ui/qr-code/qr-code.js
@@ -3,7 +3,6 @@ import React from 'react';
import qrCode from 'qrcode-generator';
import { connect } from 'react-redux';
import { isHexPrefixed } from 'ethereumjs-util';
-import ReadOnlyInput from '../readonly-input/readonly-input';
import { toChecksumHexAddress } from '../../../../shared/modules/hexstring-utils';
export default connect(mapStateToProps)(QrCodeView);
@@ -47,11 +46,7 @@ function QrCodeView(props) {
__html: qrImage.createTableTag(4),
}}
/>
-
+ {toChecksumHexAddress(data)}
);
}
diff --git a/ui/components/ui/sender-to-recipient/index.scss b/ui/components/ui/sender-to-recipient/index.scss
index 5c2c3cf5e..edd50cd4a 100644
--- a/ui/components/ui/sender-to-recipient/index.scss
+++ b/ui/components/ui/sender-to-recipient/index.scss
@@ -178,6 +178,7 @@
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
+ margin-inline-start: 8px;
[dir='rtl'] & {
/*rtl:ignore*/
diff --git a/ui/components/ui/sender-to-recipient/sender-to-recipient.component.js b/ui/components/ui/sender-to-recipient/sender-to-recipient.component.js
index 635687053..fe6655cc8 100644
--- a/ui/components/ui/sender-to-recipient/sender-to-recipient.component.js
+++ b/ui/components/ui/sender-to-recipient/sender-to-recipient.component.js
@@ -55,14 +55,12 @@ function SenderAddress({
}
}}
>
- {!addressOnly && (
-
-
-
- )}
+
+
+
{addressOnly ? (
- {`${t('from')}: ${senderName || checksummedSenderAddress}`}
+ {`${t('from')}: ${
+ senderName || shortenAddress(checksummedSenderAddress)
+ }`}
) : (
senderName
@@ -132,11 +132,9 @@ function RecipientWithAddress({
}
}}
>
- {!addressOnly && (
-
-
-
- )}
+
+
+
{addressOnly ? `${t('to')}: ` : ''}
{addressOnly
- ? recipientNickname || recipientEns || checksummedRecipientAddress
+ ? recipientNickname ||
+ recipientEns ||
+ shortenAddress(checksummedRecipientAddress)
: recipientNickname ||
recipientEns ||
recipientName ||
@@ -225,7 +225,7 @@ export default function SenderToRecipient({
/>
) : (
- {!addressOnly &&
}
+
{t('newContract')}
)}
diff --git a/ui/helpers/utils/util.js b/ui/helpers/utils/util.js
index 0cd76837e..b20e69559 100644
--- a/ui/helpers/utils/util.js
+++ b/ui/helpers/utils/util.js
@@ -13,6 +13,11 @@ import {
ROPSTEN_CHAIN_ID,
} from '../../../shared/constants/network';
import { toChecksumHexAddress } from '../../../shared/modules/hexstring-utils';
+import {
+ TRUNCATED_ADDRESS_START_CHARS,
+ TRUNCATED_NAME_CHAR_LIMIT,
+ TRUNCATED_ADDRESS_END_CHARS,
+} from '../../../shared/constants/labels';
// formatData :: ( date: ) -> String
export function formatDate(date, format = "M/d/y 'at' T") {
@@ -220,11 +225,13 @@ export function exportAsFile(filename, data, type = 'text/csv') {
* than 10 characters.
*/
export function shortenAddress(address = '') {
- if (address.length < 11) {
+ if (address.length < TRUNCATED_NAME_CHAR_LIMIT) {
return address;
}
- return `${address.slice(0, 6)}...${address.slice(-4)}`;
+ return `${address.slice(0, TRUNCATED_ADDRESS_START_CHARS)}...${address.slice(
+ -TRUNCATED_ADDRESS_END_CHARS,
+ )}`;
}
export function getAccountByAddress(accounts = [], targetAddress) {
diff --git a/ui/hooks/useTransactionDisplayData.test.js b/ui/hooks/useTransactionDisplayData.test.js
index fad81f0e0..4c35bee3b 100644
--- a/ui/hooks/useTransactionDisplayData.test.js
+++ b/ui/hooks/useTransactionDisplayData.test.js
@@ -28,7 +28,7 @@ const expectedResults = [
{
title: 'Send',
category: TRANSACTION_GROUP_CATEGORIES.SEND,
- subtitle: 'To: 0xffe5...1a97',
+ subtitle: 'To: 0xffe...1a97',
subtitleContainsOrigin: false,
date: 'May 12, 2020',
primaryCurrency: '-1 ETH',
@@ -42,7 +42,7 @@ const expectedResults = [
{
title: 'Send',
category: TRANSACTION_GROUP_CATEGORIES.SEND,
- subtitle: 'To: 0x0ccc...8848',
+ subtitle: 'To: 0x0cc...8848',
subtitleContainsOrigin: false,
date: 'May 12, 2020',
primaryCurrency: '-2 ETH',
@@ -55,7 +55,7 @@ const expectedResults = [
{
title: 'Send',
category: TRANSACTION_GROUP_CATEGORIES.SEND,
- subtitle: 'To: 0xffe5...1a97',
+ subtitle: 'To: 0xffe...1a97',
subtitleContainsOrigin: false,
date: 'May 12, 2020',
primaryCurrency: '-2 ETH',
@@ -68,7 +68,7 @@ const expectedResults = [
{
title: 'Receive',
category: TRANSACTION_GROUP_CATEGORIES.RECEIVE,
- subtitle: 'From: 0x31b9...4523',
+ subtitle: 'From: 0x31b...4523',
subtitleContainsOrigin: false,
date: 'May 12, 2020',
primaryCurrency: '18.75 ETH',
@@ -81,7 +81,7 @@ const expectedResults = [
{
title: 'Receive',
category: TRANSACTION_GROUP_CATEGORIES.RECEIVE,
- subtitle: 'From: 0x9eca...a149',
+ subtitle: 'From: 0x9ec...a149',
subtitleContainsOrigin: false,
date: 'May 8, 2020',
primaryCurrency: '0 ETH',
@@ -94,7 +94,7 @@ const expectedResults = [
{
title: 'Receive',
category: TRANSACTION_GROUP_CATEGORIES.RECEIVE,
- subtitle: 'From: 0xee01...febb',
+ subtitle: 'From: 0xee0...febb',
subtitleContainsOrigin: false,
date: 'May 24, 2020',
primaryCurrency: '1 ETH',
diff --git a/ui/pages/settings/contact-list-tab/edit-contact/edit-contact.component.js b/ui/pages/settings/contact-list-tab/edit-contact/edit-contact.component.js
index 0f64dfa15..ffefd9ea3 100644
--- a/ui/pages/settings/contact-list-tab/edit-contact/edit-contact.component.js
+++ b/ui/pages/settings/contact-list-tab/edit-contact/edit-contact.component.js
@@ -105,7 +105,14 @@ export default class EditContact extends PureComponent {
error={this.state.error}
onChange={(e) => this.setState({ newAddress: e.target.value })}
fullWidth
+ multiline
+ rows={3}
margin="dense"
+ classes={{
+ inputMultiline:
+ 'address-book__view-contact__address__text-area',
+ inputRoot: 'address-book__view-contact__address',
+ }}
/>
diff --git a/ui/pages/settings/contact-list-tab/index.scss b/ui/pages/settings/contact-list-tab/index.scss
index 8f00641b6..085a85a3f 100644
--- a/ui/pages/settings/contact-list-tab/index.scss
+++ b/ui/pages/settings/contact-list-tab/index.scss
@@ -112,6 +112,14 @@
line-height: initial !important;
}
+ &__address {
+ height: 60px !important;
+
+ textarea {
+ padding-top: 10px !important;
+ }
+ }
+
&__group {
display: flex;
flex-flow: column nowrap;
diff --git a/ui/selectors/selectors.js b/ui/selectors/selectors.js
index 434a4275f..226287024 100644
--- a/ui/selectors/selectors.js
+++ b/ui/selectors/selectors.js
@@ -15,6 +15,8 @@ import {
ALLOWED_SWAPS_CHAIN_IDS,
} from '../../shared/constants/swaps';
+import { TRUNCATED_NAME_CHAR_LIMIT } from '../../shared/constants/labels';
+
import {
shortenAddress,
getAccountByAddress,
@@ -321,7 +323,11 @@ export function getAccountsWithLabels(state) {
return getMetaMaskAccountsOrdered(state).map(
({ address, name, balance }) => ({
address,
- addressLabel: `${name} (...${address.slice(address.length - 4)})`,
+ addressLabel: `${
+ name.length < TRUNCATED_NAME_CHAR_LIMIT
+ ? name
+ : `${name.slice(0, TRUNCATED_NAME_CHAR_LIMIT - 1)}...`
+ } (${shortenAddress(address)})`,
label: name,
balance,
}),