From fbf0b9cde0c1dbc8533434db73f1da6857585acd Mon Sep 17 00:00:00 2001 From: iamacook Date: Tue, 7 Dec 2021 12:55:38 +0100 Subject: [PATCH 1/2] feat: Add module details + refactor hook --- .../SpendingLimit/InfoDisplay/AddressInfo.tsx | 9 +++-- .../Transactions/TxList/AddressInfo.tsx | 6 +-- .../TxList/SpendingLimitDetails.tsx | 39 +++++++++++++++---- .../Transactions/TxList/TxCollapsed.tsx | 22 ++++++----- .../components/Transactions/TxList/TxData.tsx | 5 ++- .../Transactions/TxList/TxInfoCreation.tsx | 27 +++++-------- .../TxList/hooks/useKnownAddress.ts | 34 +++++++++------- .../TxList/hooks/useTransactionType.ts | 16 +++----- .../components/Transactions/TxList/utils.ts | 10 ++--- src/utils/constants.ts | 7 +--- 10 files changed, 96 insertions(+), 79 deletions(-) diff --git a/src/routes/safe/components/Settings/SpendingLimit/InfoDisplay/AddressInfo.tsx b/src/routes/safe/components/Settings/SpendingLimit/InfoDisplay/AddressInfo.tsx index ebf7aea35c..13bc50e4ae 100644 --- a/src/routes/safe/components/Settings/SpendingLimit/InfoDisplay/AddressInfo.tsx +++ b/src/routes/safe/components/Settings/SpendingLimit/InfoDisplay/AddressInfo.tsx @@ -11,10 +11,12 @@ import { sameString } from 'src/utils/strings' interface AddressInfoProps { address: string title?: string + name?: string + logoUri?: string } -const AddressInfo = ({ address, title }: AddressInfoProps): ReactElement => { - const name = useSelector((state) => addressBookEntryName(state, { address })) +const AddressInfo = ({ address, title, name, logoUri }: AddressInfoProps): ReactElement => { + const addessBookName = useSelector((state) => addressBookEntryName(state, { address })) return ( <> @@ -25,11 +27,12 @@ const AddressInfo = ({ address, title }: AddressInfoProps): ReactElement => { )} ) diff --git a/src/routes/safe/components/Transactions/TxList/AddressInfo.tsx b/src/routes/safe/components/Transactions/TxList/AddressInfo.tsx index 272ac5a364..bca46a5997 100644 --- a/src/routes/safe/components/Transactions/TxList/AddressInfo.tsx +++ b/src/routes/safe/components/Transactions/TxList/AddressInfo.tsx @@ -16,7 +16,7 @@ type Props = EthHashInfoRestProps & { } export const AddressInfo = ({ address, name, avatarUrl, ...rest }: Props): ReactElement | null => { - const toInfo = useKnownAddress(address, { name, image: avatarUrl }) + const toInfo = useKnownAddress({ value: address, name: name || null, logoUri: avatarUrl || null }) if (address === '') { return null @@ -25,9 +25,9 @@ export const AddressInfo = ({ address, name, avatarUrl, ...rest }: Props): React return ( { +type SpendingLimitProps = { + txData: TransactionData + txInfo: TransactionInfo +} + +export const ModifySpendingLimitDetails = ({ txData, txInfo }: SpendingLimitProps): React.ReactElement => { + const { dataDecoded } = txData const [beneficiary, tokenAddress, amount, resetTimeMin] = useMemo( - () => data.parameters?.map(({ value }) => value) ?? [], - [data.parameters], + () => dataDecoded?.parameters?.map(({ value }) => value) ?? [], + [dataDecoded?.parameters], ) const resetTimeLabel = useMemo( @@ -40,6 +47,7 @@ export const ModifySpendingLimitDetails = ({ data }: { data: DataDecoded }): Rea ) const tokenInfo = useTokenInfo(tokenAddress as string) + const txTo = getTxTo({ txInfo }) return ( <> @@ -49,7 +57,12 @@ export const ModifySpendingLimitDetails = ({ data }: { data: DataDecoded }): Rea - + {tokenInfo && ( @@ -63,9 +76,14 @@ export const ModifySpendingLimitDetails = ({ data }: { data: DataDecoded }): Rea ) } -export const DeleteSpendingLimitDetails = ({ data }: { data: DataDecoded }): React.ReactElement => { - const [beneficiary, tokenAddress] = useMemo(() => data.parameters?.map(({ value }) => value) ?? [], [data.parameters]) +export const DeleteSpendingLimitDetails = ({ txData, txInfo }: SpendingLimitProps): React.ReactElement => { + const { dataDecoded } = txData + const [beneficiary, tokenAddress] = useMemo( + () => dataDecoded?.parameters?.map(({ value }) => value) ?? [], + [dataDecoded?.parameters], + ) const tokenInfo = useTokenInfo(tokenAddress as string) + const txTo = getTxTo({ txInfo }) return ( <> @@ -75,7 +93,12 @@ export const DeleteSpendingLimitDetails = ({ data }: { data: DataDecoded }): Rea - + {tokenInfo && } diff --git a/src/routes/safe/components/Transactions/TxList/TxCollapsed.tsx b/src/routes/safe/components/Transactions/TxList/TxCollapsed.tsx index b7e2714696..1d17ba44d2 100644 --- a/src/routes/safe/components/Transactions/TxList/TxCollapsed.tsx +++ b/src/routes/safe/components/Transactions/TxList/TxCollapsed.tsx @@ -12,7 +12,6 @@ import { } from 'src/logic/safe/store/models/types/gateway.d' import { TxCollapsedActions } from './TxCollapsedActions' import { formatDateTime, formatTime, formatTimeInWords } from 'src/utils/date' -import { KNOWN_MODULES } from 'src/utils/constants' import { sameString } from 'src/utils/strings' import { AssetInfo, isTokenTransferAsset } from './hooks/useAssetInfo' import { TransactionActions } from './hooks/useTransactionActions' @@ -24,17 +23,18 @@ import { TxsInfiniteScrollContext } from './TxsInfiniteScroll' import { TxLocationContext } from './TxLocationProvider' import { CalculatedVotes } from './TxQueueCollapsed' import { getTxTo, isCancelTxDetails } from './utils' -import { SettingsChange, DisableModule, MultiSend, Custom } from '@gnosis.pm/safe-react-gateway-sdk' +import { MultiSend, Custom } from '@gnosis.pm/safe-react-gateway-sdk' +import { useKnownAddress } from './hooks/useKnownAddress' -const TxInfo = ({ info }: { info: AssetInfo }) => { +const TxInfo = ({ info, name }: { info: AssetInfo; name?: string }) => { if (isTokenTransferAsset(info)) { return } - if (isSettingsChangeTxInfo(info)) { + if (isSettingsChangeTxInfo(info) && !isCustomTxInfo(info)) { const UNKNOWN_MODULE = 'Unknown module' - switch ((info as SettingsChange).settingsInfo?.type) { + switch (info.settingsInfo?.type) { case 'SET_FALLBACK_HANDLER': case 'ADD_OWNER': case 'REMOVE_OWNER': @@ -44,10 +44,9 @@ const TxInfo = ({ info }: { info: AssetInfo }) => { break case 'ENABLE_MODULE': case 'DISABLE_MODULE': - const disableInfo = (info as SettingsChange).settingsInfo as DisableModule return ( - {KNOWN_MODULES[disableInfo.module.value] ?? UNKNOWN_MODULE} + {name || UNKNOWN_MODULE} ) } @@ -117,6 +116,7 @@ export const TxCollapsed = ({ const { txLocation } = useContext(TxLocationContext) const { ref, lastItemId } = useContext(TxsInfiniteScrollContext) const toAddress = getTxTo(transaction) + const toInfo = useKnownAddress(toAddress) const willBeReplaced = transaction?.txStatus === 'WILL_BE_REPLACED' ? ' will-be-replaced' : '' const onChainRejection = @@ -132,14 +132,16 @@ export const TxCollapsed = ({
) - const txCollapsedInfo =
{info && }
+ const txCollapsedInfo = ( +
{info && }
+ ) const timestamp = useRef(null) diff --git a/src/routes/safe/components/Transactions/TxList/TxData.tsx b/src/routes/safe/components/Transactions/TxList/TxData.tsx index 022287bb98..a3ade321a1 100644 --- a/src/routes/safe/components/Transactions/TxList/TxData.tsx +++ b/src/routes/safe/components/Transactions/TxList/TxData.tsx @@ -81,12 +81,13 @@ export const TxData = ({ txData, txInfo }: TxDataProps): ReactElement | null => // FixMe: this way won't scale well if (isSetAllowance(txData.dataDecoded.method)) { - return + return } // FixMe: this way won't scale well if (isDeleteAllowance(txData.dataDecoded.method)) { - return + console.log(txInfo) + return } // we render the decoded data diff --git a/src/routes/safe/components/Transactions/TxList/TxInfoCreation.tsx b/src/routes/safe/components/Transactions/TxList/TxInfoCreation.tsx index 617b21eb02..581bd27661 100644 --- a/src/routes/safe/components/Transactions/TxList/TxInfoCreation.tsx +++ b/src/routes/safe/components/Transactions/TxList/TxInfoCreation.tsx @@ -14,18 +14,9 @@ export const TxInfoCreation = ({ transaction }: { transaction: Transaction }): R const txInfo = transaction.txInfo as Creation const timestamp = transaction.timestamp - const creator = useKnownAddress(txInfo.creator.value, { - name: txInfo.creator?.name, - image: txInfo.creator?.logoUri, - }) - const factory = useKnownAddress(txInfo.factory?.value, { - name: txInfo.factory?.name, - image: txInfo.factory?.logoUri, - }) - const implementation = useKnownAddress(txInfo.implementation?.value, { - name: txInfo.implementation?.name, - image: txInfo.implementation?.logoUri, - }) + const creator = useKnownAddress(txInfo.creator) + const factory = useKnownAddress(txInfo.factory) + const implementation = useKnownAddress(txInfo.implementation) return ( @@ -61,8 +52,8 @@ export const TxInfoCreation = ({ transaction }: { transaction: Transaction }): R hash={txInfo.creator.value} showCopyBtn explorerUrl={getExplorerInfo(txInfo.creator.value)} - name={creator.name} - customAvatar={creator.image} + name={creator.name || undefined} + customAvatar={creator.logoUri || undefined} showAvatar /> @@ -76,8 +67,8 @@ export const TxInfoCreation = ({ transaction }: { transaction: Transaction }): R hash={txInfo.factory.value} showCopyBtn explorerUrl={getExplorerInfo(txInfo.factory.value)} - name={factory.name} - customAvatar={factory.image} + name={factory?.name || undefined} + customAvatar={factory?.logoUri || undefined} showAvatar /> ) : ( @@ -96,8 +87,8 @@ export const TxInfoCreation = ({ transaction }: { transaction: Transaction }): R hash={txInfo.implementation.value} showCopyBtn explorerUrl={getExplorerInfo(txInfo.implementation.value)} - name={implementation.name} - customAvatar={implementation.image} + name={implementation?.name || undefined} + customAvatar={implementation?.logoUri || undefined} showAvatar /> ) : ( diff --git a/src/routes/safe/components/Transactions/TxList/hooks/useKnownAddress.ts b/src/routes/safe/components/Transactions/TxList/hooks/useKnownAddress.ts index 268387b54c..4e1e4fc091 100644 --- a/src/routes/safe/components/Transactions/TxList/hooks/useKnownAddress.ts +++ b/src/routes/safe/components/Transactions/TxList/hooks/useKnownAddress.ts @@ -3,25 +3,31 @@ import { useSelector } from 'react-redux' import { sameString } from 'src/utils/strings' import { ADDRESS_BOOK_DEFAULT_NAME } from 'src/logic/addressBook/model/addressBook' import { addressBookEntryName } from 'src/logic/addressBook/store/selectors' -import { ZERO_ADDRESS } from 'src/logic/wallets/ethAddresses' import { AddressEx } from '@gnosis.pm/safe-react-gateway-sdk' -type AddressExName = AddressEx['name'] -type AddressExImage = AddressEx['logoUri'] -type AddressInfo = { name: AddressExName | undefined; image: AddressExImage | undefined } +const DEFAULT_PROPS: AddressEx = { + value: '', + name: null, + logoUri: null, +} +export const useKnownAddress = (props: AddressEx | null = DEFAULT_PROPS): AddressEx & { isInAddressBook: boolean } => { + const recipientName = useSelector((state) => addressBookEntryName(state, { address: props?.value || '' })) -type UseKnownAddressResponse = { name: string | undefined; image: string | undefined; isAddressBook: boolean } + // Undefined known address + if (!props) { + return { + ...DEFAULT_PROPS, + isInAddressBook: false, + } + } -export const useKnownAddress = (address = ZERO_ADDRESS, { name, image }: AddressInfo): UseKnownAddressResponse => { - const recipientName = useSelector((state) => addressBookEntryName(state, { address })) // We have to check that the name returned is not UNKNOWN const isInAddressBook = !sameString(recipientName, ADDRESS_BOOK_DEFAULT_NAME) + const name = isInAddressBook && recipientName ? recipientName : props?.name - return isInAddressBook - ? { - name: recipientName, - image: undefined, - isAddressBook: true, - } - : { name: name || undefined, image: image || undefined, isAddressBook: false } + return { + ...props, + name, + isInAddressBook, + } } diff --git a/src/routes/safe/components/Transactions/TxList/hooks/useTransactionType.ts b/src/routes/safe/components/Transactions/TxList/hooks/useTransactionType.ts index 3ba62cf13e..d279a6a9c2 100644 --- a/src/routes/safe/components/Transactions/TxList/hooks/useTransactionType.ts +++ b/src/routes/safe/components/Transactions/TxList/hooks/useTransactionType.ts @@ -19,11 +19,7 @@ export const useTransactionType = (tx: Transaction): TxTypeProps => { const [type, setType] = useState({ icon: CustomTxIcon, text: 'Contract interaction' }) const safeAddress = extractSafeAddress() const toAddress = getTxTo(tx) - // Fixed casting because known address only works for Custom tx - const knownAddressBookAddress = useKnownAddress(toAddress?.value, { - name: toAddress?.name, - image: toAddress?.logoUri, - }) + const knownAddressBookAddress = useKnownAddress(toAddress) useEffect(() => { switch (tx.txInfo.type) { @@ -62,10 +58,10 @@ export const useTransactionType = (tx: Transaction): TxTypeProps => { } setType({ - icon: knownAddressBookAddress.isAddressBook + icon: knownAddressBookAddress.isInAddressBook ? CustomTxIcon - : knownAddressBookAddress.image || toAddress?.logoUri || CustomTxIcon, - fallbackIcon: knownAddressBookAddress.isAddressBook ? undefined : CustomTxIcon, + : knownAddressBookAddress.logoUri || toAddress?.logoUri || CustomTxIcon, + fallbackIcon: knownAddressBookAddress.isInAddressBook ? undefined : CustomTxIcon, text: knownAddressBookAddress.name || toAddress?.name || 'Contract interaction', }) break @@ -75,8 +71,8 @@ export const useTransactionType = (tx: Transaction): TxTypeProps => { tx, safeAddress, knownAddressBookAddress.name, - knownAddressBookAddress.image, - knownAddressBookAddress.isAddressBook, + knownAddressBookAddress.logoUri, + knownAddressBookAddress.isInAddressBook, toAddress?.logoUri, toAddress?.name, ]) diff --git a/src/routes/safe/components/Transactions/TxList/utils.ts b/src/routes/safe/components/Transactions/TxList/utils.ts index 630ac335b8..4be7b1921d 100644 --- a/src/routes/safe/components/Transactions/TxList/utils.ts +++ b/src/routes/safe/components/Transactions/TxList/utils.ts @@ -113,19 +113,19 @@ export const addressInList = (address: string): boolean => list.some((ownerAddress) => sameAddress(ownerAddress.value, address)) -export const getTxTo = (tx: Transaction): AddressEx | undefined => { - switch (tx.txInfo.type) { +export const getTxTo = ({ txInfo }: Pick): AddressEx | undefined => { + switch (txInfo.type) { case 'Transfer': { - return tx.txInfo.recipient + return txInfo.recipient } case 'SettingsChange': { return undefined } case 'Custom': { - return tx.txInfo.to + return txInfo.to } case 'Creation': { - return tx.txInfo.factory || undefined + return txInfo.factory || undefined } } } diff --git a/src/utils/constants.ts b/src/utils/constants.ts index 5328f93911..57e1b35437 100644 --- a/src/utils/constants.ts +++ b/src/utils/constants.ts @@ -39,9 +39,4 @@ export const GATEWAY_URL = IS_PRODUCTION export const IPFS_GATEWAY = process.env.REACT_APP_IPFS_GATEWAY export const SPENDING_LIMIT_MODULE_ADDRESS = process.env.REACT_APP_SPENDING_LIMIT_MODULE_ADDRESS || '0xCFbFaC74C26F8647cBDb8c5caf80BB5b32E43134' -export const GNOSISDAO_SAFESNAP_MODULE_ADDRESS = - process.env.GNOSISDAO_SAFESNAP_MODULE_ADDRESS || '0x0eBaC21F7f6A6599B5fa5f57Baaa974ADFEC4613' -export const KNOWN_MODULES = { - [SPENDING_LIMIT_MODULE_ADDRESS]: 'Spending limit', - [GNOSISDAO_SAFESNAP_MODULE_ADDRESS]: 'GnosisDAO SafeSnap', -} +// TODO: Remove GNOSISDAO_SAFESNAP_MODULE_ADDRESS from GitHub secrets From cd076b6a0a5176350c132a6fbc1d932ff281cb61 Mon Sep 17 00:00:00 2001 From: iamacook Date: Tue, 7 Dec 2021 16:17:53 +0100 Subject: [PATCH 2/2] fix: Remove log --- src/routes/safe/components/Transactions/TxList/TxData.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/routes/safe/components/Transactions/TxList/TxData.tsx b/src/routes/safe/components/Transactions/TxList/TxData.tsx index a3ade321a1..d23ab2580c 100644 --- a/src/routes/safe/components/Transactions/TxList/TxData.tsx +++ b/src/routes/safe/components/Transactions/TxList/TxData.tsx @@ -86,7 +86,6 @@ export const TxData = ({ txData, txInfo }: TxDataProps): ReactElement | null => // FixMe: this way won't scale well if (isDeleteAllowance(txData.dataDecoded.method)) { - console.log(txInfo) return }