diff --git a/src/components/AppLayout/Sidebar/SafeHeader/index.tsx b/src/components/AppLayout/Sidebar/SafeHeader/index.tsx
index 16a0268d..ee1503d4 100644
--- a/src/components/AppLayout/Sidebar/SafeHeader/index.tsx
+++ b/src/components/AppLayout/Sidebar/SafeHeader/index.tsx
@@ -130,10 +130,13 @@ const SafeHeader = ({
return (
<>
+ {/* Network */}
{networkInfo.label}
+
+ {/* Identicon */}
@@ -142,6 +145,7 @@ const SafeHeader = ({
+ {/* SafeInfo */}
{safeName}
diff --git a/src/components/AppLayout/Sidebar/index.tsx b/src/components/AppLayout/Sidebar/index.tsx
index 673b994d..ff2b29d3 100644
--- a/src/components/AppLayout/Sidebar/index.tsx
+++ b/src/components/AppLayout/Sidebar/index.tsx
@@ -16,7 +16,7 @@ const HelpContainer = styled.div`
const HelpCenterLink = styled.a`
height: 30px;
width: 166px;
- padding: 6px 0 0 16px;
+ padding: 8px 0 8px 16px;
margin: 14px 0px;
text-decoration: none;
display: block;
diff --git a/src/components/AppLayout/index.tsx b/src/components/AppLayout/index.tsx
index 4ac72c9e..63c2c1ba 100644
--- a/src/components/AppLayout/index.tsx
+++ b/src/components/AppLayout/index.tsx
@@ -6,53 +6,62 @@ import Header from './Header'
import Footer from './Footer'
import Sidebar from './Sidebar'
-const Grid = styled.div`
- height: 100%;
- overflow: auto;
+const Container = styled.div`
+ height: 100vh;
+ width: 100vw;
+ display: flex;
+ flex-direction: column;
+
background-color: ${({ theme }) => theme.colors.background};
- display: grid;
- grid-template-columns: 200px 1fr;
- grid-template-rows: 54px 1fr;
- grid-template-areas:
- 'topbar topbar'
- 'sidebar body';
`
-const GridTopbarWrapper = styled.nav`
+const HeaderWrapper = styled.nav`
+ height: 54px;
+ width: 100%;
+ z-index: 1;
+
background-color: white;
- box-shadow: 0 2px 4px 0 rgba(212, 212, 211, 0.59);
- border-bottom: 2px solid ${({ theme }) => theme.colors.separator};
- z-index: 999;
- grid-area: topbar;
+ box-shadow: 0 0 4px 0 rgba(212, 212, 211, 0.59);
`
-const GridSidebarWrapper = styled.aside`
- width: 200px;
- padding: 62px 8px 0 8px;
+const BodyWrapper = styled.div`
+ height: calc(100% - 54px);
+ width: 100%;
+ display: flex;
+ flex-direction: row;
+`
+
+const SidebarWrapper = styled.aside`
height: 100%;
+ width: 200px;
+ display: flex;
+ flex-direction: column;
+ z-index: 1;
+
+ padding: 8px;
background-color: ${({ theme }) => theme.colors.white};
border-right: 2px solid ${({ theme }) => theme.colors.separator};
+`
+
+const ContentWrapper = styled.section`
+ width: 100%;
display: flex;
flex-direction: column;
- box-sizing: border-box;
- position: fixed;
- grid-area: sidebar;
-`
+ overflow-x: auto;
-const GridBodyWrapper = styled.section`
- margin: 0 16px 0 16px;
- grid-area: body;
- display: flex;
- flex-direction: column;
- align-content: stretch;
-`
+ padding: 0 16px;
-export const BodyWrapper = styled.div`
- flex: 1 100%;
-`
+ > :nth-child(1) {
+ flex-grow: 1;
+ width: 100%;
+ align-items: center;
+ justify-content: center;
+ }
-export const FooterWrapper = styled.footer`
- margin: 0 16px;
+ > :nth-child(2) {
+ width: 100%;
+ height: 59px;
+ }
`
type Props = {
@@ -77,29 +86,29 @@ const Layout: React.FC = ({
children,
sidebarItems,
}): React.ReactElement => (
-
-
+
+
-
-
-
-
-
- {children}
-
+
+
+
+
+
+
+ {children}
-
-
-
+
+
+
)
export default Layout
diff --git a/src/components/forms/validator.test.ts b/src/components/forms/validator.test.ts
index 0eff1983..3f5d45ef 100644
--- a/src/components/forms/validator.test.ts
+++ b/src/components/forms/validator.test.ts
@@ -169,13 +169,19 @@ describe('Forms > Validators', () => {
it('Returns undefined for an address not contained in the passed array', async () => {
const addresses = ['0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe']
- expect(uniqueAddress(addresses)('0xe7e3272a84cf3fe180345b9f7234ba705eB5E2CA')).toBeUndefined()
+ expect(uniqueAddress(addresses)()).toBeUndefined()
})
- it('Returns an error message for an address already contained in the array', async () => {
- const addresses = ['0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe']
+ it('Returns an error message for an array with duplicated values', async () => {
+ const addresses = ['0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe', '0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe']
- expect(uniqueAddress(addresses)(addresses[0])).toEqual(ADDRESS_REPEATED_ERROR)
+ expect(uniqueAddress(addresses)()).toEqual(ADDRESS_REPEATED_ERROR)
+ })
+
+ it('Returns an error message for an array with duplicated checksum and not checksum values', async () => {
+ const addresses = ['0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe', '0xde0b295669a9fd93d5f28d9ec85e40f4cb697bae']
+
+ expect(uniqueAddress(addresses)()).toEqual(ADDRESS_REPEATED_ERROR)
})
})
diff --git a/src/components/forms/validator.ts b/src/components/forms/validator.ts
index e6f2d9d5..1f01b4d0 100644
--- a/src/components/forms/validator.ts
+++ b/src/components/forms/validator.ts
@@ -1,13 +1,11 @@
-import { List } from 'immutable'
+import { getWeb3 } from 'src/logic/wallets/getWeb3'
import memoize from 'lodash.memoize'
import { isFeatureEnabled } from 'src/config'
import { FEATURES } from 'src/config/networks/network.d'
-
-import { sameAddress } from 'src/logic/wallets/ethAddresses'
-import { getWeb3 } from 'src/logic/wallets/getWeb3'
+import { List } from 'immutable'
type ValidatorReturnType = string | undefined
-type GenericValidatorType = (...args: unknown[]) => ValidatorReturnType
+export type GenericValidatorType = (...args: unknown[]) => ValidatorReturnType
type AsyncValidator = (...args: unknown[]) => Promise
export type Validator = GenericValidatorType | AsyncValidator
@@ -89,13 +87,18 @@ export const minMaxLength = (minLen: number, maxLen: number) => (value: string):
export const ADDRESS_REPEATED_ERROR = 'Address already introduced'
-export const uniqueAddress = (addresses: string[] | List): GenericValidatorType =>
- memoize(
- (value: string): ValidatorReturnType => {
- const addressAlreadyExists = addresses.some((address) => sameAddress(value, address))
- return addressAlreadyExists ? ADDRESS_REPEATED_ERROR : undefined
- },
- )
+export const uniqueAddress = (addresses: string[] | List): GenericValidatorType => (): ValidatorReturnType => {
+ // @ts-expect-error both list and array have signatures for map but TS thinks they're not compatible
+ const lowercaseAddresses = addresses.map((address) => address.toLowerCase())
+ const uniqueAddresses = new Set(lowercaseAddresses)
+ const lengthPropName = 'size' in addresses ? 'size' : 'length'
+
+ if (uniqueAddresses.size !== addresses?.[lengthPropName]) {
+ return ADDRESS_REPEATED_ERROR
+ }
+
+ return undefined
+}
export const composeValidators = (...validators: Validator[]) => (value: unknown): ValidatorReturnType =>
validators.reduce(
diff --git a/src/logic/addressBook/store/selectors/index.ts b/src/logic/addressBook/store/selectors/index.ts
index 7460909f..128b9aa7 100644
--- a/src/logic/addressBook/store/selectors/index.ts
+++ b/src/logic/addressBook/store/selectors/index.ts
@@ -8,6 +8,10 @@ import { AddressBookState } from 'src/logic/addressBook/model/addressBook'
export const addressBookSelector = (state: AppReduxState): AddressBookState => state[ADDRESS_BOOK_REDUCER_ID]
+export const addressBookAddressesListSelector = createSelector(addressBookSelector, (addressBook): string[] => {
+ return addressBook.map((entry) => entry.address)
+})
+
export const getNameFromAddressBookSelector = createSelector(
addressBookSelector,
(_, address) => address,
diff --git a/src/logic/addressBook/utils/__tests__/addressBookUtils.test.ts b/src/logic/addressBook/utils/__tests__/addressBookUtils.test.ts
index 4541c2f7..8ff40278 100644
--- a/src/logic/addressBook/utils/__tests__/addressBookUtils.test.ts
+++ b/src/logic/addressBook/utils/__tests__/addressBookUtils.test.ts
@@ -2,7 +2,6 @@ import { List } from 'immutable'
import {
checkIfEntryWasDeletedFromAddressBook,
getAddressBookFromStorage,
- getAddressesListFromAddressBook,
getNameFromAddressBook,
getOwnersWithNameFromAddressBook,
isValidAddressBookName,
@@ -28,24 +27,6 @@ const getMockOldAddressBookEntry = ({ address = '', name = '', isOwner = false }
}
}
-describe('getAddressesListFromAdbk', () => {
- const entry1 = getMockAddressBookEntry('123456', 'test1')
- const entry2 = getMockAddressBookEntry('78910', 'test2')
- const entry3 = getMockAddressBookEntry('4781321', 'test3')
-
- it('It should returns the list of addresses within the addressBook given a safeAddressBook', () => {
- // given
- const safeAddressBook = [entry1, entry2, entry3]
- const expectedResult = [entry1.address, entry2.address, entry3.address]
-
- // when
- const result = getAddressesListFromAddressBook(safeAddressBook)
-
- // then
- expect(result).toStrictEqual(expectedResult)
- })
-})
-
describe('getNameFromSafeAddressBook', () => {
const entry1 = getMockAddressBookEntry('123456', 'test1')
const entry2 = getMockAddressBookEntry('78910', 'test2')
diff --git a/src/logic/addressBook/utils/index.ts b/src/logic/addressBook/utils/index.ts
index 11656a8b..f4e835de 100644
--- a/src/logic/addressBook/utils/index.ts
+++ b/src/logic/addressBook/utils/index.ts
@@ -56,9 +56,6 @@ export const saveAddressBook = async (addressBook: AddressBookState): Promise
- addressBook.map((entry) => entry.address)
-
type GetNameFromAddressBookOptions = {
filterOnlyValidName: boolean
}
diff --git a/src/logic/collectibles/utils/index.ts b/src/logic/collectibles/utils/index.ts
index c117aead..8f7b346b 100644
--- a/src/logic/collectibles/utils/index.ts
+++ b/src/logic/collectibles/utils/index.ts
@@ -1,4 +1,4 @@
-import { getNetworkId } from 'src/config'
+import { getNetworkId, getNetworkInfo } from 'src/config'
import { ETHEREUM_NETWORK } from 'src/config/networks/network.d'
import { nftAssetsListAddressesSelector } from 'src/logic/collectibles/store/selectors'
import { TxServiceModel } from 'src/logic/safe/store/actions/transactions/fetchTransactions/loadOutgoingTransactions'
@@ -18,6 +18,14 @@ export const CK_ADDRESS = {
[ETHEREUM_NETWORK.RINKEBY]: '0x16baf0de678e52367adc69fd067e5edd1d33e3bf',
}
+// Note: xDAI ENS is missing, once we have it we need to add it here
+const ENS_CONTRACT_ADDRESS = {
+ [ETHEREUM_NETWORK.MAINNET]: '0x57f1887a8BF19b14fC0dF6Fd9B2acc9Af147eA85',
+ [ETHEREUM_NETWORK.RINKEBY]: '0x57f1887a8BF19b14fC0dF6Fd9B2acc9Af147eA85',
+ [ETHEREUM_NETWORK.ENERGY_WEB_CHAIN]: '0x0A6d64413c07E10E890220BBE1c49170080C6Ca0',
+ [ETHEREUM_NETWORK.VOLTA]: '0xd7CeF70Ba7efc2035256d828d5287e2D285CD1ac',
+}
+
// safeTransferFrom(address,address,uint256)
export const SAFE_TRANSFER_FROM_WITHOUT_DATA_HASH = '42842e0e'
@@ -50,12 +58,11 @@ export const getERC721Symbol = async (contractAddress: string): Promise
try {
const ERC721token = await getERC721TokenContract()
const tokenInstance = await ERC721token.at(contractAddress)
- tokenSymbol = tokenInstance.symbol()
+ tokenSymbol = await tokenInstance.symbol()
} catch (err) {
// If the contract address is an ENS token contract, we know that the ERC721 standard is not proper implemented
// The method symbol() is missing
- const ENS_TOKEN_CONTRACT = '0x57f1887a8BF19b14fC0dF6Fd9B2acc9Af147eA85'
- if (sameAddress(contractAddress, ENS_TOKEN_CONTRACT)) {
+ if (isENSContract(contractAddress)) {
return 'ENS'
}
console.error(`Failed to retrieve token symbol for ERC721 token ${contractAddress}`)
@@ -64,6 +71,11 @@ export const getERC721Symbol = async (contractAddress: string): Promise
return tokenSymbol
}
+export const isENSContract = (contractAddress: string): boolean => {
+ const { id } = getNetworkInfo()
+ return sameAddress(contractAddress, ENS_CONTRACT_ADDRESS[id])
+}
+
/**
* Verifies if the provided contract is a valid ERC721
* @param {string} contractAddress
diff --git a/src/logic/safe/store/actions/transactions/fetchTransactions/loadIncomingTransactions.ts b/src/logic/safe/store/actions/transactions/fetchTransactions/loadIncomingTransactions.ts
index d52130a9..2a8d8bab 100644
--- a/src/logic/safe/store/actions/transactions/fetchTransactions/loadIncomingTransactions.ts
+++ b/src/logic/safe/store/actions/transactions/fetchTransactions/loadIncomingTransactions.ts
@@ -10,6 +10,7 @@ import { web3ReadOnly } from 'src/logic/wallets/getWeb3'
import { makeIncomingTransaction } from 'src/logic/safe/store/models/incomingTransaction'
import fetchTransactions from 'src/logic/safe/store/actions/transactions/fetchTransactions/fetchTransactions'
import { TransactionTypes } from 'src/logic/safe/store/models/types/transaction'
+import { isENSContract } from 'src/logic/collectibles/utils'
export type IncomingTxServiceModel = {
blockNumber: number
@@ -76,12 +77,18 @@ const batchIncomingTxsTokenDataRequest = (txs: IncomingTxServiceModel[]) => {
batch.execute()
return Promise.all(whenTxsValues).then((txsValues) =>
- txsValues.map(([tx, symbol, decimals, ethTx, ethTxReceipt]) => [
- tx,
- symbol ? symbol : nativeCoin.symbol,
- decimals ? decimals : nativeCoin.decimals,
- new bn(ethTx?.gasPrice ?? 0).times(ethTxReceipt?.gasUsed ?? 0),
- ]),
+ txsValues.map(([tx, symbolFetched, decimals, ethTx, ethTxReceipt]) => {
+ let symbol = symbolFetched
+ if (!symbolFetched) {
+ symbol = isENSContract(tx.tokenAddress) ? 'ENS' : nativeCoin.symbol
+ }
+ return [
+ tx,
+ symbol,
+ decimals ? decimals : nativeCoin.decimals,
+ new bn(ethTx?.gasPrice ?? 0).times(ethTxReceipt?.gasUsed ?? 0),
+ ]
+ }),
)
}
diff --git a/src/logic/safe/store/selectors/index.ts b/src/logic/safe/store/selectors/index.ts
index df9d6de6..63449c96 100644
--- a/src/logic/safe/store/selectors/index.ts
+++ b/src/logic/safe/store/selectors/index.ts
@@ -208,6 +208,17 @@ export const safeModulesSelector = createSelector(safeSelector, safeFieldSelecto
export const safeFeaturesEnabledSelector = createSelector(safeSelector, safeFieldSelector('featuresEnabled'))
+export const safeOwnersAddressesListSelector = createSelector(
+ safeOwnersSelector,
+ (owners): List => {
+ if (!owners) {
+ return List([])
+ }
+
+ return owners?.map(({ address }) => address)
+ },
+)
+
export const getActiveTokensAddressesForAllSafes = createSelector(safesListSelector, (safes) => {
const addresses = Set().withMutations((set) => {
safes.forEach((safe) => {
diff --git a/src/routes/open/components/Layout.tsx b/src/routes/open/components/Layout.tsx
index 0aef861f..6ad2a29f 100644
--- a/src/routes/open/components/Layout.tsx
+++ b/src/routes/open/components/Layout.tsx
@@ -9,7 +9,7 @@ import Row from 'src/components/layout/Row'
import { initContracts } from 'src/logic/contracts/safeContracts'
import Review from 'src/routes/open/components/ReviewInformation'
import SafeNameField from 'src/routes/open/components/SafeNameForm'
-import SafeOwnersFields from 'src/routes/open/components/SafeOwnersConfirmationsForm'
+import { SafeOwnersPage } from 'src/routes/open/components/SafeOwnersConfirmationsForm'
import {
FIELD_CONFIRMATIONS,
FIELD_SAFE_NAME,
@@ -129,7 +129,7 @@ const Layout = (props: LayoutProps): React.ReactElement => {
testId="create-safe-form"
>
-
+
diff --git a/src/routes/open/components/SafeOwnersConfirmationsForm/index.tsx b/src/routes/open/components/SafeOwnersConfirmationsForm/index.tsx
index 6951f19a..cee758fd 100644
--- a/src/routes/open/components/SafeOwnersConfirmationsForm/index.tsx
+++ b/src/routes/open/components/SafeOwnersConfirmationsForm/index.tsx
@@ -236,21 +236,13 @@ const SafeOwnersForm = (props): React.ReactElement => {
)
}
-const SafeOwnersPage = ({ updateInitialProps }) =>
+export const SafeOwnersPage = () =>
function OpenSafeOwnersPage(controls, { errors, form, values }) {
return (
<>
-
+
>
)
}
-
-export default SafeOwnersPage
diff --git a/src/routes/open/components/SafeOwnersConfirmationsForm/validators.ts b/src/routes/open/components/SafeOwnersConfirmationsForm/validators.ts
index f37cb4b3..b528a0f5 100644
--- a/src/routes/open/components/SafeOwnersConfirmationsForm/validators.ts
+++ b/src/routes/open/components/SafeOwnersConfirmationsForm/validators.ts
@@ -1,6 +1,6 @@
-import { uniqueAddress } from 'src/components/forms/validator'
+import { GenericValidatorType, uniqueAddress } from 'src/components/forms/validator'
-export const getAddressValidator = (addresses, position) => {
+export const getAddressValidator = (addresses: string[], position: number): GenericValidatorType => {
// thanks Rich Harris
// https://twitter.com/Rich_Harris/status/1125850391155965952
const copy = addresses.slice()
diff --git a/src/routes/open/utils/safeDataExtractor.ts b/src/routes/open/utils/safeDataExtractor.ts
index f7a85b04..08baa207 100644
--- a/src/routes/open/utils/safeDataExtractor.ts
+++ b/src/routes/open/utils/safeDataExtractor.ts
@@ -1,7 +1,7 @@
import { List } from 'immutable'
import { makeOwner } from 'src/logic/safe/store/models/owner'
-import { SafeOwner } from '../../../logic/safe/store/models/safe'
+import { SafeOwner } from 'src/logic/safe/store/models/safe'
export const getAccountsFrom = (values) => {
const accounts = Object.keys(values)
diff --git a/src/routes/safe/components/AddressBook/CreateEditEntryModal/index.tsx b/src/routes/safe/components/AddressBook/CreateEditEntryModal/index.tsx
index c8c5073a..d77d11e0 100644
--- a/src/routes/safe/components/AddressBook/CreateEditEntryModal/index.tsx
+++ b/src/routes/safe/components/AddressBook/CreateEditEntryModal/index.tsx
@@ -19,8 +19,7 @@ import Col from 'src/components/layout/Col'
import Hairline from 'src/components/layout/Hairline'
import Paragraph from 'src/components/layout/Paragraph'
import Row from 'src/components/layout/Row'
-import { addressBookSelector } from 'src/logic/addressBook/store/selectors'
-import { getAddressesListFromAddressBook } from 'src/logic/addressBook/utils'
+import { addressBookAddressesListSelector } from 'src/logic/addressBook/store/selectors'
export const CREATE_ENTRY_INPUT_NAME_ID = 'create-entry-input-name'
export const CREATE_ENTRY_INPUT_ADDRESS_ID = 'create-entry-input-address'
@@ -42,8 +41,7 @@ const CreateEditEntryModalComponent = ({
}
}
- const addressBook = useSelector(addressBookSelector)
- const addressBookAddressesList = getAddressesListFromAddressBook(addressBook)
+ const addressBookAddressesList = useSelector(addressBookAddressesListSelector)
const entryDoesntExist = uniqueAddress(addressBookAddressesList)
const formMutators = {
diff --git a/src/routes/safe/components/Balances/SendModal/index.tsx b/src/routes/safe/components/Balances/SendModal/index.tsx
index a10b046f..71e6823e 100644
--- a/src/routes/safe/components/Balances/SendModal/index.tsx
+++ b/src/routes/safe/components/Balances/SendModal/index.tsx
@@ -9,7 +9,7 @@ import { CustomTx } from './screens/ContractInteraction/ReviewCustomTx'
import { ContractInteractionTx } from './screens/ContractInteraction'
import { CustomTxProps } from './screens/ContractInteraction/SendCustomTx'
import { ReviewTxProp } from './screens/ReviewTx'
-import { NFTToken } from 'src/logic/collectibles/sources/collectibles'
+import { NFTToken } from 'src/logic/collectibles/sources/collectibles.d'
import { SendCollectibleTxInfo } from './screens/SendCollectible'
const ChooseTxType = React.lazy(() => import('./screens/ChooseTxType'))
diff --git a/src/routes/safe/components/Balances/SendModal/screens/SendCollectible/CollectibleSelectField/index.tsx b/src/routes/safe/components/Balances/SendModal/screens/SendCollectible/CollectibleSelectField/index.tsx
index 9bb111e9..ddb24d1f 100644
--- a/src/routes/safe/components/Balances/SendModal/screens/SendCollectible/CollectibleSelectField/index.tsx
+++ b/src/routes/safe/components/Balances/SendModal/screens/SendCollectible/CollectibleSelectField/index.tsx
@@ -13,7 +13,7 @@ import Img from 'src/components/layout/Img'
import Paragraph from 'src/components/layout/Paragraph'
import { setImageToPlaceholder } from 'src/routes/safe/components/Balances/utils'
import { textShortener } from 'src/utils/strings'
-import { NFTToken } from 'src/logic/collectibles/sources/collectibles'
+import { NFTToken } from 'src/logic/collectibles/sources/collectibles.d'
const useSelectedCollectibleStyles = makeStyles(selectedTokenStyles)
diff --git a/src/routes/safe/components/Balances/SendModal/screens/SendCollectible/TokenSelectField/index.tsx b/src/routes/safe/components/Balances/SendModal/screens/SendCollectible/TokenSelectField/index.tsx
index d276caca..dab0e19c 100644
--- a/src/routes/safe/components/Balances/SendModal/screens/SendCollectible/TokenSelectField/index.tsx
+++ b/src/routes/safe/components/Balances/SendModal/screens/SendCollectible/TokenSelectField/index.tsx
@@ -14,7 +14,7 @@ import Paragraph from 'src/components/layout/Paragraph'
import { formatAmount } from 'src/logic/tokens/utils/formatAmount'
import { setImageToPlaceholder } from 'src/routes/safe/components/Balances/utils'
import { textShortener } from 'src/utils/strings'
-import { NFTAssets } from 'src/logic/collectibles/sources/collectibles'
+import { NFTAssets } from 'src/logic/collectibles/sources/collectibles.d'
const useSelectedTokenStyles = makeStyles(selectedTokenStyles)
diff --git a/src/routes/safe/components/Balances/SendModal/screens/SendCollectible/index.tsx b/src/routes/safe/components/Balances/SendModal/screens/SendCollectible/index.tsx
index 671a9b70..e56bf7e4 100644
--- a/src/routes/safe/components/Balances/SendModal/screens/SendCollectible/index.tsx
+++ b/src/routes/safe/components/Balances/SendModal/screens/SendCollectible/index.tsx
@@ -21,7 +21,7 @@ import { getNameFromAddressBook } from 'src/logic/addressBook/utils'
import { nftTokensSelector, safeActiveSelectorMap } from 'src/logic/collectibles/store/selectors'
import SafeInfo from 'src/routes/safe/components/Balances/SendModal/SafeInfo'
import { AddressBookInput } from 'src/routes/safe/components/Balances/SendModal/screens/AddressBookInput'
-import { NFTToken } from 'src/logic/collectibles/sources/collectibles'
+import { NFTToken } from 'src/logic/collectibles/sources/collectibles.d'
import { getExplorerInfo } from 'src/config'
import { sameAddress } from 'src/logic/wallets/ethAddresses'
import { sm } from 'src/theme/variables'
diff --git a/src/routes/safe/components/Settings/ManageOwners/AddOwnerModal/index.tsx b/src/routes/safe/components/Settings/ManageOwners/AddOwnerModal/index.tsx
index 88a170fa..a4e73801 100644
--- a/src/routes/safe/components/Settings/ManageOwners/AddOwnerModal/index.tsx
+++ b/src/routes/safe/components/Settings/ManageOwners/AddOwnerModal/index.tsx
@@ -2,7 +2,7 @@ import { createStyles, makeStyles } from '@material-ui/core/styles'
import React, { useEffect, useState } from 'react'
import { useDispatch, useSelector } from 'react-redux'
-import OwnerForm from './screens/OwnerForm'
+import { OwnerForm } from './screens/OwnerForm'
import ReviewAddOwner from './screens/Review'
import ThresholdForm from './screens/ThresholdForm'
@@ -16,7 +16,7 @@ import createTransaction from 'src/logic/safe/store/actions/createTransaction'
import { safeParamAddressFromStateSelector } from 'src/logic/safe/store/selectors'
import { checksumAddress } from 'src/utils/checksumAddress'
import { makeAddressBookEntry } from 'src/logic/addressBook/model/addressBook'
-import { Dispatch } from 'src/logic/safe/store/actions/types'
+import { Dispatch } from 'src/logic/safe/store/actions/types.d'
const styles = createStyles({
biggerModalWindow: {
diff --git a/src/routes/safe/components/Settings/ManageOwners/AddOwnerModal/screens/OwnerForm/index.tsx b/src/routes/safe/components/Settings/ManageOwners/AddOwnerModal/screens/OwnerForm/index.tsx
index 85d304e3..73083d62 100644
--- a/src/routes/safe/components/Settings/ManageOwners/AddOwnerModal/screens/OwnerForm/index.tsx
+++ b/src/routes/safe/components/Settings/ManageOwners/AddOwnerModal/screens/OwnerForm/index.tsx
@@ -1,5 +1,5 @@
import IconButton from '@material-ui/core/IconButton'
-import { withStyles } from '@material-ui/core/styles'
+import { makeStyles } from '@material-ui/core/styles'
import Close from '@material-ui/icons/Close'
import React from 'react'
import { useSelector } from 'react-redux'
@@ -18,7 +18,7 @@ import Col from 'src/components/layout/Col'
import Hairline from 'src/components/layout/Hairline'
import Paragraph from 'src/components/layout/Paragraph'
import Row from 'src/components/layout/Row'
-import { safeOwnersSelector } from 'src/logic/safe/store/selectors'
+import { safeOwnersAddressesListSelector } from 'src/logic/safe/store/selectors'
export const ADD_OWNER_NAME_INPUT_TEST_ID = 'add-owner-name-input'
export const ADD_OWNER_ADDRESS_INPUT_TEST_ID = 'add-owner-address-testid'
@@ -30,12 +30,20 @@ const formMutators = {
},
}
-const OwnerForm = ({ classes, onClose, onSubmit }) => {
+const useStyles = makeStyles(styles)
+
+type OwnerFormProps = {
+ onClose: () => void
+ onSubmit: (values) => void
+}
+
+export const OwnerForm = ({ onClose, onSubmit }: OwnerFormProps): React.ReactElement => {
+ const classes = useStyles()
const handleSubmit = (values) => {
onSubmit(values)
}
- const owners = useSelector(safeOwnersSelector)
- const ownerDoesntExist = uniqueAddress(owners?.map((o) => o.address) || [])
+ const owners = useSelector(safeOwnersAddressesListSelector)
+ const ownerDoesntExist = uniqueAddress(owners)
return (
<>
@@ -72,7 +80,6 @@ const OwnerForm = ({ classes, onClose, onSubmit }) => {
{
{
-