From 5181488b05c721c6cec024ba69291a0021b3c870 Mon Sep 17 00:00:00 2001 From: veado <61792675+veado@users.noreply.github.com> Date: Mon, 2 Jan 2023 18:58:05 +0100 Subject: [PATCH] Hide private data - pt.1 (#2515) - [x] `SymDeposit` - [x] `Swap` - [x] `EditableAddress` - [x] `MaxBalanceButton` --- .../deposit/add/SymDeposit.stories.tsx | 3 +- .../components/deposit/add/SymDeposit.tsx | 57 +++++++++++-------- .../swap/EditableAddress.stories.tsx | 3 +- .../components/swap/EditableAddress.tsx | 9 ++- src/renderer/components/swap/Swap.stories.tsx | 3 +- src/renderer/components/swap/Swap.tsx | 18 ++++-- .../uielements/button/MaxBalanceButton.tsx | 18 ++++-- .../assets/AssetsTableCollapsable.stories.tsx | 1 + .../wallet/assets/AssetsTableCollapsable.tsx | 16 +++--- .../components/wallet/assets/TotalValue.tsx | 18 +++--- src/renderer/helpers/stringHelper.ts | 1 + .../views/deposit/add/SymDepositView.tsx | 4 ++ src/renderer/views/swap/SwapView.tsx | 2 + src/renderer/views/wallet/AssetsView.tsx | 4 ++ src/renderer/views/wallet/PoolShareView.tsx | 2 + 15 files changed, 104 insertions(+), 55 deletions(-) diff --git a/src/renderer/components/deposit/add/SymDeposit.stories.tsx b/src/renderer/components/deposit/add/SymDeposit.stories.tsx index 6f84b1735..c9ec7eb99 100644 --- a/src/renderer/components/deposit/add/SymDeposit.stories.tsx +++ b/src/renderer/components/deposit/add/SymDeposit.stories.tsx @@ -134,7 +134,8 @@ const defaultProps: SymDepositProps = { hasAsymAssets: RD.initial, symAssetMismatch: RD.initial, openRecoveryTool: () => console.log('openRecoveryTool'), - openAsymDepositTool: () => console.log('openAsymDepositTool') + openAsymDepositTool: () => console.log('openAsymDepositTool'), + hidePrivateData: false } export const Default: Story = () => diff --git a/src/renderer/components/deposit/add/SymDeposit.tsx b/src/renderer/components/deposit/add/SymDeposit.tsx index bd8bcf9f1..068c24d91 100644 --- a/src/renderer/components/deposit/add/SymDeposit.tsx +++ b/src/renderer/components/deposit/add/SymDeposit.tsx @@ -48,7 +48,7 @@ import { eqBaseAmount, eqOAsset, eqOApproveParams, eqAsset } from '../../../help import { sequenceSOption, sequenceTOption } from '../../../helpers/fpHelpers' import * as PoolHelpers from '../../../helpers/poolHelper' import { liveData, LiveData } from '../../../helpers/rx/liveData' -import { emptyString, loadingString, noDataString } from '../../../helpers/stringHelper' +import { emptyString, hiddenString, loadingString, noDataString } from '../../../helpers/stringHelper' import * as WalletHelper from '../../../helpers/walletHelper' import { useSubscriptionState } from '../../../hooks/useSubscriptionState' import { INITIAL_SYM_DEPOSIT_STATE } from '../../../services/chain/const' @@ -153,6 +153,7 @@ export type Props = { hasAsymAssets: LiquidityProviderHasAsymAssetsRD symAssetMismatch: LiquidityProviderAssetMismatchRD openAsymDepositTool: FP.Lazy + hidePrivateData: boolean } type SelectedInput = 'asset' | 'rune' | 'none' @@ -193,7 +194,8 @@ export const SymDeposit: React.FC = (props) => { openRecoveryTool, hasAsymAssets: hasAsymAssetsRD, symAssetMismatch: symAssetMismatchRD, - openAsymDepositTool + openAsymDepositTool, + hidePrivateData } = props const intl = useIntl() @@ -240,16 +242,18 @@ export const SymDeposit: React.FC = (props) => { : FP.pipe( oRuneWB, O.map(({ amount, asset }) => - formatAssetAmountCurrency({ - amount: baseToAsset(amount), - asset, - decimal: 8, - trimZeros: true - }) + hidePrivateData + ? hiddenString + : formatAssetAmountCurrency({ + amount: baseToAsset(amount), + asset, + decimal: 8, + trimZeros: true + }) ), O.getOrElse(() => noDataString) ), - [oRuneWB, walletBalancesLoading] + [hidePrivateData, oRuneWB, walletBalancesLoading] ) const oAssetWB: O.Option = useMemo(() => { @@ -268,16 +272,18 @@ export const SymDeposit: React.FC = (props) => { : FP.pipe( oAssetWB, O.map(({ amount, asset }) => - formatAssetAmountCurrency({ - amount: baseToAsset(amount), - asset, - decimal: 8, - trimZeros: true - }) + hidePrivateData + ? hiddenString + : formatAssetAmountCurrency({ + amount: baseToAsset(amount), + asset, + decimal: 8, + trimZeros: true + }) ), O.getOrElse(() => noDataString) ), - [oAssetWB, walletBalancesLoading] + [hidePrivateData, oAssetWB, walletBalancesLoading] ) const hasAssetLedger = useMemo( @@ -1844,6 +1850,7 @@ export const SymDeposit: React.FC = (props) => { { id: 'deposit.add.max.infoWithFee' }, { balance: runeBalanceLabel, fee: runeFeeLabel } )} + hidePrivateData={hidePrivateData} /> {minRuneAmountError && renderMinAmount({ @@ -1892,6 +1899,7 @@ export const SymDeposit: React.FC = (props) => { ) : intl.formatMessage({ id: 'deposit.add.max.info' }, { balance: assetBalanceLabel }) } + hidePrivateData={hidePrivateData} /> {minAssetAmountError && renderMinAmount({ @@ -1903,15 +1911,16 @@ export const SymDeposit: React.FC = (props) => { ), [ + maxAssetAmountToDepositMax1e8, asset, - updateAssetAmount, + intl, assetBalanceLabel, assetFeeLabel, - intl, - maxAssetAmountToDepositMax1e8, + hidePrivateData, minAssetAmountError, + renderMinAmount, minAssetAmountToDepositMax1e8, - renderMinAmount + updateAssetAmount ] ) @@ -2086,7 +2095,7 @@ export const SymDeposit: React.FC = (props) => { oRuneWB, O.map(({ walletAddress: address }) => ( - {address} + {hidePrivateData ? hiddenString : address} )), O.getOrElse(() => <>{noDataString}) @@ -2101,7 +2110,7 @@ export const SymDeposit: React.FC = (props) => { oAssetWB, O.map(({ walletAddress: address }) => ( - {address} + {hidePrivateData ? hiddenString : address} )), O.getOrElse(() => <>{noDataString}) @@ -2179,7 +2188,7 @@ export const SymDeposit: React.FC = (props) => { oDepositParams, O.map(({ memos: { rune: memo } }) => ( - {memo} + {hidePrivateData ? hiddenString : memo} )), O.toNullable @@ -2209,7 +2218,7 @@ export const SymDeposit: React.FC = (props) => { oDepositParams, O.map(({ memos: { asset: memo } }) => ( - {memo} + {hidePrivateData ? hiddenString : memo} )), O.toNullable diff --git a/src/renderer/components/swap/EditableAddress.stories.tsx b/src/renderer/components/swap/EditableAddress.stories.tsx index 611802950..c8cf810c1 100644 --- a/src/renderer/components/swap/EditableAddress.stories.tsx +++ b/src/renderer/components/swap/EditableAddress.stories.tsx @@ -15,7 +15,8 @@ const defaultProps: EditableAddressProps = { onChangeAddress: () => console.log('address changed'), onChangeEditableAddress: () => console.log('address changed'), onChangeEditableMode: () => console.log('edit mode changed'), - addressValidator: (address: Address) => Promise.resolve(eqString.equals(address, bnbAddress)) + addressValidator: (address: Address) => Promise.resolve(eqString.equals(address, bnbAddress)), + hidePrivateData: false } export const Default: StoryFn = () => diff --git a/src/renderer/components/swap/EditableAddress.tsx b/src/renderer/components/swap/EditableAddress.tsx index 4d46f4613..22687b110 100644 --- a/src/renderer/components/swap/EditableAddress.tsx +++ b/src/renderer/components/swap/EditableAddress.tsx @@ -9,6 +9,7 @@ import { useIntl } from 'react-intl' import { Network } from '../../../shared/api/types' import { truncateAddress } from '../../helpers/addressHelper' +import { hiddenString } from '../../helpers/stringHelper' import { AddressValidationAsync } from '../../services/clients' import { InnerForm } from '../shared/form' import { BaseButton } from '../uielements/button' @@ -24,6 +25,7 @@ export type EditableAddressProps = { onChangeEditableAddress: (address: Address) => void onChangeEditableMode: (editModeActive: boolean) => void addressValidator: AddressValidationAsync + hidePrivateData: boolean } export const EditableAddress = ({ asset, @@ -33,7 +35,8 @@ export const EditableAddress = ({ onClickOpenAddress, onChangeEditableMode, addressValidator, - network + network, + hidePrivateData }: EditableAddressProps) => { const RECIPIENT_FIELD = 'recipient' const intl = useIntl() @@ -100,7 +103,7 @@ export const EditableAddress = ({ setEditableAddress(O.fromNullable(address)) onChangeEditableMode(true) }}> - {truncatedAddress} + {hidePrivateData ? hiddenString : truncatedAddress}
@@ -119,7 +122,7 @@ export const EditableAddress = ({
) - }, [address, truncatedAddress, onChangeEditableMode, onClickOpenAddress]) + }, [address, hidePrivateData, truncatedAddress, onChangeEditableMode, onClickOpenAddress]) const renderEditableAddress = useCallback( (editableAddress: Address) => { diff --git a/src/renderer/components/swap/Swap.stories.tsx b/src/renderer/components/swap/Swap.stories.tsx index 2b66bd0e1..0146797be 100644 --- a/src/renderer/components/swap/Swap.stories.tsx +++ b/src/renderer/components/swap/Swap.stories.tsx @@ -117,7 +117,8 @@ const defaultProps: SwapProps = { isApprovedERC20Token$: () => Rx.of(RD.success(true)), importWalletHandler: () => console.log('import wallet'), clickAddressLinkHandler: () => console.log('handle click on address'), - addressValidator: () => Promise.resolve(true) + addressValidator: () => Promise.resolve(true), + hidePrivateData: false } export const Default: StoryFn = () => diff --git a/src/renderer/components/swap/Swap.tsx b/src/renderer/components/swap/Swap.tsx index 75d2bae57..c00ab7fa3 100644 --- a/src/renderer/components/swap/Swap.tsx +++ b/src/renderer/components/swap/Swap.tsx @@ -51,7 +51,7 @@ import { eqAsset, eqBaseAmount, eqOAsset, eqOApproveParams, eqAddress } from '.. import { sequenceSOption, sequenceTOption } from '../../helpers/fpHelpers' import * as PoolHelpers from '../../helpers/poolHelper' import { liveData, LiveData } from '../../helpers/rx/liveData' -import { emptyString, loadingString, noDataString } from '../../helpers/stringHelper' +import { emptyString, hiddenString, loadingString, noDataString } from '../../helpers/stringHelper' import { filterWalletBalancesByAssets, getWalletBalanceByAssetAndWalletType, @@ -169,6 +169,7 @@ export type SwapProps = { disableSwapAction: boolean clickAddressLinkHandler: (address: Address) => void addressValidator: AddressValidationAsync + hidePrivateData: boolean } export const Swap = ({ @@ -208,7 +209,8 @@ export const Swap = ({ importWalletHandler, disableSwapAction, clickAddressLinkHandler, - addressValidator + addressValidator, + hidePrivateData }: SwapProps) => { const intl = useIntl() @@ -1684,6 +1686,7 @@ export const Swap = ({ balance={{ amount: maxAmountToSwapMax1e8, asset: sourceAsset }} onClick={() => setAmountToSwapMax1e8(maxAmountToSwapMax1e8)} maxInfoText={maxBalanceInfoTxt} + hidePrivateData={hidePrivateData} /> {minAmountError && renderMinAmount} @@ -1732,6 +1735,7 @@ export const Swap = ({ onChangeEditableAddress={onChangeEditableRecipientAddress} onChangeEditableMode={(editModeActive) => setCustomAddressEditActive(editModeActive)} addressValidator={addressValidator} + hidePrivateData={hidePrivateData} /> )), @@ -1925,7 +1929,7 @@ export const Swap = ({ oSourceWalletAddress, O.map((address) => ( - {address} + {hidePrivateData ? hiddenString : address} )), O.getOrElse(() => <>{noDataString}) @@ -1940,7 +1944,7 @@ export const Swap = ({ oRecipientAddress, O.map((address) => ( - {address} + {hidePrivateData ? hiddenString : address} )), O.getOrElse(() => <>{noDataString}) @@ -1983,6 +1987,8 @@ export const Swap = ({
{walletBalancesLoading ? loadingString + : hidePrivateData + ? hiddenString : formatAssetAmountCurrency({ amount: baseToAsset(sourceAssetAmountMax1e8), asset: sourceAsset, @@ -2006,7 +2012,9 @@ export const Swap = ({
{memoTitle}
-
{memoLabel}
+
+ {hidePrivateData ? hiddenString : memoLabel} +
)}
diff --git a/src/renderer/components/uielements/button/MaxBalanceButton.tsx b/src/renderer/components/uielements/button/MaxBalanceButton.tsx index 1a1d55cb7..d9e3cc429 100644 --- a/src/renderer/components/uielements/button/MaxBalanceButton.tsx +++ b/src/renderer/components/uielements/button/MaxBalanceButton.tsx @@ -4,6 +4,7 @@ import { Balance } from '@xchainjs/xchain-client' import { BaseAmount, baseToAsset, formatAssetAmountCurrency } from '@xchainjs/xchain-util' import { useIntl } from 'react-intl' +import { hiddenString } from '../../../helpers/stringHelper' import { InfoIcon } from '../info' import { TextButton, Props as ButtonProps } from './TextButton' @@ -15,6 +16,8 @@ export type ComponentProps = { className?: string classNameButton?: string classNameIcon?: string + // TODO (@veado) Make it default (not) optional to handle private data everyhere properly + hidePrivateData?: boolean } export type Props = ComponentProps & Omit @@ -29,7 +32,8 @@ export const MaxBalanceButton: React.FC = (props): JSX.Element => { size = 'normal', className = '', classNameButton = '', - classNameIcon = '' + classNameIcon = '', + hidePrivateData = false } = props const { amount, asset } = balance @@ -47,11 +51,13 @@ export const MaxBalanceButton: React.FC = (props): JSX.Element => { className={`mr-5px w-auto !p-0 ${classNameButton} whitespace-nowrap`}> {intl.formatMessage({ id: 'common.max' })}:   - {formatAssetAmountCurrency({ - amount: baseToAsset(amount), - asset, - trimZeros: true - })} + {hidePrivateData + ? hiddenString + : formatAssetAmountCurrency({ + amount: baseToAsset(amount), + asset, + trimZeros: true + })} {maxInfoText && } diff --git a/src/renderer/components/wallet/assets/AssetsTableCollapsable.stories.tsx b/src/renderer/components/wallet/assets/AssetsTableCollapsable.stories.tsx index 051d98b90..6025f315b 100644 --- a/src/renderer/components/wallet/assets/AssetsTableCollapsable.stories.tsx +++ b/src/renderer/components/wallet/assets/AssetsTableCollapsable.stories.tsx @@ -182,6 +182,7 @@ const Template = (args: Partial>) => { pricePool={RUNE_PRICE_POOL} network="testnet" mimirHalt={RD.initial} + hidePrivateData={false} /> ) } diff --git a/src/renderer/components/wallet/assets/AssetsTableCollapsable.tsx b/src/renderer/components/wallet/assets/AssetsTableCollapsable.tsx index a012d67dc..964364a78 100644 --- a/src/renderer/components/wallet/assets/AssetsTableCollapsable.tsx +++ b/src/renderer/components/wallet/assets/AssetsTableCollapsable.tsx @@ -29,7 +29,7 @@ import { DEFAULT_WALLET_TYPE } from '../../../const' import { disableRuneUpgrade, isNonNativeRuneAsset, isRuneNativeAsset, isUSDAsset } from '../../../helpers/assetHelper' import { getChainAsset } from '../../../helpers/chainHelper' import { getDeepestPool, getPoolPriceValue } from '../../../helpers/poolHelper' -import { noDataString } from '../../../helpers/stringHelper' +import { hiddenString, noDataString } from '../../../helpers/stringHelper' import * as poolsRoutes from '../../../routes/pools' import { WalletBalancesRD } from '../../../services/clients' import { PoolDetails, PoolsDataMap } from '../../../services/midgard/types' @@ -63,6 +63,7 @@ type Props = { assetHandler: (asset: SelectedWalletAsset, action: AssetAction) => void network: Network mimirHalt: MimirHaltRD + hidePrivateData: boolean } export const AssetsTableCollapsable: React.FC = (props): JSX.Element => { @@ -74,7 +75,8 @@ export const AssetsTableCollapsable: React.FC = (props): JSX.Element => { selectAssetHandler, assetHandler, mimirHalt: mimirHaltRD, - network + network, + hidePrivateData } = props const intl = useIntl() @@ -159,13 +161,13 @@ export const AssetsTableCollapsable: React.FC = (props): JSX.Element => { ) return (
-
{balance}
-
{price}
+
{hidePrivateData ? hiddenString : balance}
+
{hidePrivateData ? hiddenString : price}
) } }), - [network, poolDetails, pricePool] + [hidePrivateData, network, poolDetails, pricePool] ) const renderActionColumn = useCallback( @@ -431,7 +433,7 @@ export const AssetsTableCollapsable: React.FC = (props): JSX.Element => { - {walletAddress} + {hidePrivateData ? hiddenString : walletAddress} { event.preventDefault() @@ -456,7 +458,7 @@ export const AssetsTableCollapsable: React.FC = (props): JSX.Element => { ) }, - [intl, renderBalances] + [hidePrivateData, intl, renderBalances] ) // open all panels by default diff --git a/src/renderer/components/wallet/assets/TotalValue.tsx b/src/renderer/components/wallet/assets/TotalValue.tsx index 44287e366..cea6f9617 100644 --- a/src/renderer/components/wallet/assets/TotalValue.tsx +++ b/src/renderer/components/wallet/assets/TotalValue.tsx @@ -6,6 +6,7 @@ import * as FP from 'fp-ts/lib/function' import { useIntl } from 'react-intl' import { isUSDAsset } from '../../../helpers/assetHelper' +import { hiddenString } from '../../../helpers/stringHelper' import { BaseAmountRD } from '../../../types' import { PricePool } from '../../../views/pools/Pools.types' import { InfoIcon } from '../../uielements/info' @@ -16,10 +17,11 @@ type Props = { total: BaseAmountRD title: string info?: string + hidePrivateData: boolean } export const TotalValue: React.FC = (props): JSX.Element => { - const { pricePool, total: totalRD, title, info } = props + const { pricePool, total: totalRD, title, info, hidePrivateData } = props const intl = useIntl() @@ -37,16 +39,18 @@ export const TotalValue: React.FC = (props): JSX.Element => { ), (total) => ( - {formatAssetAmountCurrency({ - amount: baseToAsset(total), - asset: pricePool.asset, - decimal: isUSDAsset(pricePool.asset) ? 2 : 4 - })} + {hidePrivateData + ? hiddenString + : formatAssetAmountCurrency({ + amount: baseToAsset(total), + asset: pricePool.asset, + decimal: isUSDAsset(pricePool.asset) ? 2 : 4 + })} ) ) ), - [intl, pricePool.asset, totalRD] + [hidePrivateData, intl, pricePool.asset, totalRD] ) return ( diff --git a/src/renderer/helpers/stringHelper.ts b/src/renderer/helpers/stringHelper.ts index 823affbcc..33c0cc281 100644 --- a/src/renderer/helpers/stringHelper.ts +++ b/src/renderer/helpers/stringHelper.ts @@ -18,6 +18,7 @@ export const compareShallowStr = (str1: string, str2: string): boolean => { export const emptyString = '' export const loadingString = '...' export const noDataString = '--' +export const hiddenString = '******' export const truncateMiddle = ( text: string, diff --git a/src/renderer/views/deposit/add/SymDepositView.tsx b/src/renderer/views/deposit/add/SymDepositView.tsx index 92a400c3e..28c5f7d89 100644 --- a/src/renderer/views/deposit/add/SymDepositView.tsx +++ b/src/renderer/views/deposit/add/SymDepositView.tsx @@ -213,6 +213,8 @@ export const SymDepositView: React.FC = (props) => { openAsymDepositTool={openAsymDepositTool} assetWalletType={assetWalletAddress.type} runeWalletType={runeWalletAddress.type} + // TODO (@veado) Handle private data + hidePrivateData={false} /> ), @@ -295,6 +297,8 @@ export const SymDepositView: React.FC = (props) => { openAsymDepositTool={openAsymDepositTool} assetWalletType={assetWalletAddress.type} runeWalletType={runeWalletAddress.type} + // TODO (@veado) Handle private data + hidePrivateData={false} /> ) diff --git a/src/renderer/views/swap/SwapView.tsx b/src/renderer/views/swap/SwapView.tsx index 72b821ab1..944565370 100644 --- a/src/renderer/views/swap/SwapView.tsx +++ b/src/renderer/views/swap/SwapView.tsx @@ -422,6 +422,8 @@ const SuccessRouteView: React.FC = ({ importWalletHandler={importWalletHandler} clickAddressLinkHandler={openAddressUrl} addressValidator={validateSwapAddress} + // TODO (@veado) Handle private data + hidePrivateData={false} /> ) } diff --git a/src/renderer/views/wallet/AssetsView.tsx b/src/renderer/views/wallet/AssetsView.tsx index 116410422..774ced22e 100644 --- a/src/renderer/views/wallet/AssetsView.tsx +++ b/src/renderer/views/wallet/AssetsView.tsx @@ -121,6 +121,8 @@ export const AssetsView: React.FC = (): JSX.Element => { pricePool={selectedPricePool} title={intl.formatMessage({ id: 'wallet.balance.total.poolAssets' })} info={intl.formatMessage({ id: 'wallet.balance.total.poolAssets.info' })} + // TODO (@veado) Handle private data + hidePrivateData={false} /> { assetHandler={assetHandler} mimirHalt={mimirHaltRD} network={network} + // TODO (@veado) Handle private data + hidePrivateData={false} /> ) diff --git a/src/renderer/views/wallet/PoolShareView.tsx b/src/renderer/views/wallet/PoolShareView.tsx index 358b32a2b..0c648ba26 100644 --- a/src/renderer/views/wallet/PoolShareView.tsx +++ b/src/renderer/views/wallet/PoolShareView.tsx @@ -177,6 +177,8 @@ export const PoolShareView: React.FC = (): JSX.Element => { total={sharesTotalRD} pricePool={selectedPricePool} title={intl.formatMessage({ id: 'wallet.shares.total' })} + // TODO (@veado) Handle private data + hidePrivateData={false} /> ) }, [allSharesRD, intl, poolDetailsRD, pricePoolData, selectedPricePool])