Skip to content

Commit

Permalink
Merge pull request #878 from multiversx/tm-send-usernames-new
Browse files Browse the repository at this point in the history
Usernames' support
  • Loading branch information
Miro Mărgineanu authored Jul 27, 2023
2 parents cbe4d4b + 1025247 commit 5090fa3
Show file tree
Hide file tree
Showing 25 changed files with 13,348 additions and 13,116 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,15 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

- [Added usernames' support](https://github.com/multiversx/mx-sdk-dapp/pull/878)

## [[v2.19.0]](https://github.com/multiversx/mx-sdk-dapp/pull/877)] - 2023-07-26

- [Fixed NextJS provider double mounting](https://github.com/multiversx/mx-sdk-dapp/pull/876)

## [[v2.18.5]](https://github.com/multiversx/mx-sdk-dapp/pull/875)] - 2023-07-24

- [Fixed `optionalRedirect` `setTimout` usage and window redirect](https://github.com/multiversx/mx-sdk-dapp/pull/873)
- [Fixed ledger signing reconnect](https://github.com/multiversx/mx-sdk-dapp/pull/874)
- [Added ledger transport mock](https://github.com/multiversx/mx-sdk-dapp/pull/871)
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@
"classnames": "2.3.1",
"platform": "1.3.6",
"qrcode": "1.5.0",
"swr": "1.1.2"
"swr": "2.2.0"
},
"files": [
"*.js",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,10 @@ export const SignStepBody = ({
tokenId: nonce && nonce?.length > 0 ? nftId : tokenId
});

const transactionReceiver = multiTxData
? new Address(receiver).bech32()
: currentTransaction.transaction.getReceiver().toString();

const getFormattedAmount = ({ addCommas }: { addCommas: boolean }) =>
formatAmount({
input: isTokenTransaction
Expand Down Expand Up @@ -129,11 +133,7 @@ export const SignStepBody = ({

<ConfirmReceiver
scamReport={scamReport}
receiver={
multiTxData
? new Address(receiver).bech32()
: currentTransaction.transaction.getReceiver().toString()
}
receiver={transactionReceiver}
/>

<div className={styles.columns}>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,34 +1,70 @@
import React from 'react';

import { faExclamationTriangle } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import classNames from 'classnames';

import { useGetAccountFromApi } from 'hooks';
import { LoadingDots } from 'UI/LoadingDots';
import { isContract } from 'utils/smartContracts';

import { ReceiverSubValue } from './components/ReceiverSubValue';
import { ReceiverValue } from './components/ReceiverValue';
import styles from './confirmReceiverStyles.scss';

export interface ConfirmReceiverPropsType {
receiver?: string;
receiver: string;
scamReport: string | null;
}

export const ConfirmReceiver = (props: ConfirmReceiverPropsType) => {
const { receiver, scamReport } = props;
export const ConfirmReceiver = ({
receiver,
scamReport
}: ConfirmReceiverPropsType) => {
const isSmartContract = isContract(receiver);

const {
account: usernameAccount,
loading: usernameAccountLoading,
error: usernameAccountError
} = useGetAccountFromApi(receiver, { shouldSkipFetching: isSmartContract });

const receiverValue = usernameAccount?.username ?? receiver;
const hasUsername = Boolean(
receiver && Boolean(usernameAccount?.username) && !usernameAccountError
);

return (
<div className={styles.receiver}>
<span className={styles.label}>Receiver</span>

{receiver && (
<span className={styles.value} data-testid='confirmReceiver'>
{receiver}
{usernameAccountLoading ? (
<LoadingDots className={styles.loadingDots} />
) : (
<span data-testid='confirmReceiver' className={styles.valueWrapper}>
<ReceiverValue
hasUsername={hasUsername}
receiverAddress={receiver}
receiverValue={receiverValue}
/>
</span>
)}

{usernameAccountLoading ? (
<LoadingDots
className={classNames(styles.loadingDots, styles.absolute)}
/>
) : (
<ReceiverSubValue hasUsername={hasUsername} receiver={receiver} />
)}

{scamReport && (
<div className={styles.scam}>
<span>
<FontAwesomeIcon
icon={faExclamationTriangle}
className={styles.icon}
/>

<small data-testid='confirmScamReport'>{scamReport}</small>
</span>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import React from 'react';

import { ACCOUNTS_ENDPOINT } from 'apiCalls';
import { CopyButton } from 'UI/CopyButton';
import { ExplorerLink } from 'UI/ExplorerLink';
import { Trim } from 'UI/Trim';
import { isContract } from 'utils';

import styles from './receiverSubValueStyles.scss';

export interface ReceiverSubValuePropsType {
hasUsername: boolean;
receiver: string;
}

export const ReceiverSubValue = ({
hasUsername,
receiver
}: ReceiverSubValuePropsType) => {
const isSmartContract = isContract(receiver);

if (hasUsername) {
return (
<span className={styles.subValue}>
<Trim text={receiver} className={styles.subValueTrim} />
<CopyButton text={receiver} className={styles.subValueCopy} />
</span>
);
}

if (isSmartContract) {
return (
<span className={styles.subValue}>
<Trim text='Smart Contract Call' className={styles.subValueTrim} />

<ExplorerLink
page={`/${ACCOUNTS_ENDPOINT}/${receiver}`}
className={styles.subValueExplorer}
/>
</span>
);
}

return (
<span className={styles.subValue}>
<Trim text='View in Explorer' className={styles.subValueTrim} />

<ExplorerLink
page={`/${ACCOUNTS_ENDPOINT}/${receiver}`}
className={styles.subValueExplorer}
/>
</span>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './ReceiverSubValue';
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
.subValue {
display: flex;
align-items: center;
gap: 8px;
height: 16px;
position: absolute;
right: 0;
bottom: 0;
left: 0;

.subValueTrim {
line-height: 1;
color: var(--dapp-form-placeholder-color);
font-size: 12px;
display: flex;
align-items: flex-end;
max-width: none;

[class*='left'] *,
[class*='right'] * {
color: var(--dapp-form-placeholder-color);
font-size: 12px !important;
}
}

.subValueCopy {
font-size: 12px;
}

.subValueExplorer {
margin-left: 0;
font-size: 12px;

svg {
color: var(--dapp-form-placeholder-color) !important;
}

&:hover svg {
color: var(--dapp-form-btn-bg) !important;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import React from 'react';
import classNames from 'classnames';

import { ACCOUNTS_ENDPOINT } from 'apiCalls';
import MultiversXIconSimple from 'assets/icons/mvx-icon-simple.svg';
import { CopyButton } from 'UI/CopyButton';
import { ExplorerLink } from 'UI/ExplorerLink';
import { Trim } from 'UI/Trim';

import { trimReceiverDomain } from '../../helpers';
import styles from './receiverValueStyles.scss';

export interface ReceiverValuePropsType {
hasUsername: boolean;
receiverValue: string;
receiverAddress: string;
}

export const ReceiverValue = ({
hasUsername,
receiverValue,
receiverAddress
}: ReceiverValuePropsType) => {
if (hasUsername) {
return (
<span className={classNames(styles.receiverValue, styles.shrunk)}>
<MultiversXIconSimple className={styles.receiverValueIcon} />
{trimReceiverDomain(receiverValue)}

<ExplorerLink
page={`/${ACCOUNTS_ENDPOINT}/${receiverAddress}`}
className={styles.receiverValueExplorer}
/>
</span>
);
}

return (
<span className={styles.receiverValue}>
<Trim text={receiverAddress} />
<CopyButton text={receiverAddress} className={styles.receiverValueCopy} />
</span>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './ReceiverValue';
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
.receiverValue {
word-break: break-all;
line-height: 1.5;
height: 16px;
gap: 8px;
display: flex;
align-items: center;

&.shrunk {
line-height: 1;
height: auto;
}

.receiverValueIcon {
height: 16px;
position: relative;
width: auto;
top: 1px;
}

.receiverValueCopy {
font-size: 12px;
}

.receiverValueExplorer {
margin-left: 0;
font-size: 12px;

svg {
color: var(--dapp-form-placeholder-color) !important;
}

&:hover svg {
color: var(--dapp-form-btn-bg) !important;
}
}
}
Original file line number Diff line number Diff line change
@@ -1,20 +1,41 @@
.receiver {
text-align: left;
display: flex;
flex-direction: column;
gap: 8px;
position: relative;
padding-bottom: 24px;
width: 100%;

.value {
font-size: 16px;
word-break: break-all;
line-height: 1.5;
display: block;
color: #e5e5e5;
.valueWrapper {
font-size: 14px;
}

.label {
margin-bottom: 8px;
color: #a3a3a3;
font-size: 12px;
line-height: 1;
font-weight: 400;
display: block;
}

.icon {
height: 16px;
position: relative;
width: auto;
top: 1px;
}

.loadingDots {
font-size: 16px;
line-height: 1;
height: 16px;

&.absolute {
left: 0;
right: 0;
bottom: 0;
position: absolute;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './trimReceiverDomain';
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
export const trimReceiverDomain = (receiver?: string) => {
if (!receiver) {
return;
}

const trimmedPartBeforeLastDot = receiver.substring(
0,
receiver.lastIndexOf('.')
);

return trimmedPartBeforeLastDot;
};
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
display: flex;
flex-direction: column;
margin: auto;
width: 100%;

.fields {
gap: 32px;
Expand Down
1 change: 1 addition & 0 deletions src/apiCalls/accounts/getAccountFromApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export async function getAccountFromApi(address?: string) {
if (!address) {
return null;
}

const apiAddress = getCleanApiAddress();
const configUrl = `${apiAddress}/${ACCOUNTS_ENDPOINT}/${address}?withGuardianInfo=true`;

Expand Down
1 change: 1 addition & 0 deletions src/apiCalls/transactions/getTransactions.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export interface GetTransactionsType {
condition?: 'should' | 'must';
before?: number;
withScResults?: boolean;
withUsername?: boolean;
status?: TransactionServerStatusesEnum;
/**
* Search in data object
Expand Down
Loading

0 comments on commit 5090fa3

Please sign in to comment.