WIP: fix typings (?)

Not so sure about how robust the fix is. But allow me to continue developing
This commit is contained in:
fernandomg 2020-06-30 15:49:47 -03:00
parent ec09b3bd55
commit dc75d97083
21 changed files with 930 additions and 84 deletions

View File

@ -203,7 +203,7 @@
"reselect": "^4.0.0",
"semver": "7.3.2",
"styled-components": "^5.0.1",
"truffle-contract": "4.0.31",
"truffle-contract": "^4.0.31",
"web3": "1.2.8"
},
"devDependencies": {
@ -214,6 +214,7 @@
"@types/node": "14.0.12",
"@types/react": "^16.9.32",
"@types/react-dom": "^16.9.6",
"@types/react-redux": "^7.1.9",
"@types/styled-components": "^5.1.0",
"@typescript-eslint/eslint-plugin": "3.2.0",
"@typescript-eslint/parser": "3.2.0",

View File

@ -39,10 +39,10 @@ const StyledBlock = styled(Block)`
interface Props {
safeName?: string
safeAddress: string
ethBalance?: string
ethBalance?: number | string
}
const AddressInfo = ({ ethBalance, safeAddress, safeName }: Props) => {
const AddressInfo: React.FC<Props> = ({ ethBalance, safeAddress, safeName }: Props) => {
return (
<Wrapper>
<div className="icon-section">

View File

@ -1,3 +1,5 @@
import { List } from 'immutable'
import { sameAddress } from 'src/logic/wallets/ethAddresses'
import { getWeb3 } from 'src/logic/wallets/getWeb3'
@ -92,7 +94,7 @@ export const minMaxLength = (minLen, maxLen) => (value) =>
export const ADDRESS_REPEATED_ERROR = 'Address already introduced'
export const uniqueAddress = (addresses: string[]) =>
export const uniqueAddress = (addresses: string[] | List<string>) =>
simpleMemoize((value: string[]) => {
const addressAlreadyExists = addresses.some((address) => sameAddress(value, address))
return addressAlreadyExists ? ADDRESS_REPEATED_ERROR : undefined

View File

@ -4,8 +4,13 @@ import { getNetwork } from 'src/config'
import { getConfiguredSource } from 'src/logic/collectibles/sources'
import { addNftAssets, addNftTokens } from 'src/logic/collectibles/store/actions/addCollectibles'
import { safeParamAddressFromStateSelector } from 'src/routes/safe/store/selectors'
import { Dispatch } from 'redux'
import { GnosisState } from 'src/store'
const fetchCollectibles = () => async (dispatch, getState) => {
const fetchCollectibles = (): ((dispatch: Dispatch, getState: () => GnosisState) => Promise<void>) => async (
dispatch,
getState,
) => {
const network = getNetwork()
const safeAddress = safeParamAddressFromStateSelector(getState()) || ''
const source = getConfiguredSource()

View File

@ -4,10 +4,11 @@ import GnosisSafeSol from '@gnosis.pm/safe-contracts/build/contracts/GnosisSafe.
import SafeProxy from '@gnosis.pm/safe-contracts/build/contracts/GnosisSafeProxy.json'
import { ensureOnce } from 'src/utils/singleton'
import { simpleMemoize } from 'src/components/forms/validator'
import { getWeb3, getNetworkIdFrom } from 'src/logic/wallets/getWeb3'
import { getNetworkIdFrom, getWeb3 } from 'src/logic/wallets/getWeb3'
import { calculateGasOf, calculateGasPrice } from 'src/logic/wallets/ethTransactions'
import { ZERO_ADDRESS } from 'src/logic/wallets/ethAddresses'
import { isProxyCode } from 'src/logic/contracts/historicProxyCode'
import Web3 from 'web3'
export const SENTINEL_ADDRESS = '0x0000000000000000000000000000000000000001'
export const MULTI_SEND_ADDRESS = '0xB522a9f781924eD250A11C54105E51840B138AdD'
@ -19,7 +20,7 @@ export const SAFE_MASTER_COPY_ADDRESS_V10 = '0xb6029EA3B2c51D09a50B53CA8012FeEB0
let proxyFactoryMaster
let safeMaster
const createGnosisSafeContract = (web3) => {
const createGnosisSafeContract = (web3: Web3): any => {
const gnosisSafe = contract(GnosisSafeSol)
gnosisSafe.setProvider(web3.currentProvider)
@ -72,7 +73,7 @@ export const getSafeMasterContract = async () => {
export const getSafeDeploymentTransaction = (safeAccounts, numConfirmations, userAccount) => {
const gnosisSafeData = safeMaster.contract.methods
.setup(safeAccounts, numConfirmations, ZERO_ADDRESS, '0x', DEFAULT_FALLBACK_HANDLER_ADDRESS, ZERO_ADDRESS, 0, ZERO_ADDRESS)
.encodeABI()
.encodeABI()
return proxyFactoryMaster.methods.createProxy(safeMaster.address, gnosisSafeData)
}
@ -94,11 +95,10 @@ export const estimateGasForDeployingSafe = async (
return gas * parseInt(gasPrice, 10)
}
export const getGnosisSafeInstanceAt = simpleMemoize(async (safeAddress) => {
export const getGnosisSafeInstanceAt = simpleMemoize(async (safeAddress): Promise<any> => {
const web3 = getWeb3()
const GnosisSafe = await getGnosisSafeContract(web3)
const gnosisSafe = await GnosisSafe.at(safeAddress)
return gnosisSafe
return GnosisSafe.at(safeAddress)
})
const cleanByteCodeMetadata = (bytecode) => {

View File

@ -10,7 +10,7 @@ export const FEATURES = [
{ name: 'ERC1155', validVersion: '>=1.1.1' },
]
export const safeNeedsUpdate = (currentVersion, latestVersion) => {
export const safeNeedsUpdate = (currentVersion: string, latestVersion: string): boolean => {
if (!currentVersion || !latestVersion) {
return false
}
@ -21,9 +21,10 @@ export const safeNeedsUpdate = (currentVersion, latestVersion) => {
return latest ? semverLessThan(current, latest) : false
}
export const getCurrentSafeVersion = (gnosisSafeInstance) => gnosisSafeInstance.VERSION()
export const getCurrentSafeVersion = (gnosisSafeInstance: { VERSION: () => Promise<string> }): Promise<string> =>
gnosisSafeInstance.VERSION()
export const enabledFeatures = (version) =>
export const enabledFeatures = (version: string): Array<string> =>
FEATURES.reduce((acc, feature) => {
if (semverSatisfies(version, feature.validVersion)) {
acc.push(feature.name)
@ -31,7 +32,16 @@ export const enabledFeatures = (version) =>
return acc
}, [])
export const checkIfSafeNeedsUpdate = async (gnosisSafeInstance, lastSafeVersion) => {
interface SafeInfo {
current: string
latest: string
needUpdate: boolean
}
export const checkIfSafeNeedsUpdate = async (
gnosisSafeInstance: { VERSION: () => Promise<string> },
lastSafeVersion: string,
): Promise<SafeInfo> => {
if (!gnosisSafeInstance || !lastSafeVersion) {
return null
}
@ -43,7 +53,7 @@ export const checkIfSafeNeedsUpdate = async (gnosisSafeInstance, lastSafeVersion
return { current, latest, needUpdate }
}
export const getCurrentMasterContractLastVersion = async () => {
export const getCurrentMasterContractLastVersion = async (): Promise<string> => {
const safeMaster = await getSafeMasterContract()
let safeMasterVersion
try {
@ -56,7 +66,7 @@ export const getCurrentMasterContractLastVersion = async () => {
return safeMasterVersion
}
export const getSafeVersionInfo = async (safeAddress) => {
export const getSafeVersionInfo = async (safeAddress: string): Promise<SafeInfo> => {
try {
const safeMaster = await getGnosisSafeInstanceAt(safeAddress)
const lastSafeVersion = await getCurrentMasterContractLastVersion()

View File

@ -3,8 +3,9 @@ import { createSelector } from 'reselect'
import { TOKEN_REDUCER_ID } from 'src/logic/tokens/store/reducer/tokens'
import { Token } from '../model/token'
import { GnosisState } from 'src/store'
export const tokensSelector = (state: Map<string, unknown>): Map<string, Token> => state[TOKEN_REDUCER_ID]
export const tokensSelector = (state: GnosisState): Map<string, Token> => state[TOKEN_REDUCER_ID]
export const tokenListSelector = createSelector(tokensSelector, (tokens) => tokens.toList())

View File

@ -74,7 +74,7 @@ const isTxValid = (t: SafeAppTx): boolean => {
const confirmTransactions = (
safeAddress: string,
safeName: string,
ethBalance: string,
ethBalance: number | string,
nameApp: string,
iconApp: string,
txs: Array<SafeAppTx>,

View File

@ -36,7 +36,7 @@ const EthValue = ({ onSetMax }: EthValueProps) => {
</Paragraph>
<ButtonLink
color={disabled ? 'disabled' : 'secondary'}
onClick={() => !disabled && onSetMax(ethBalance)}
onClick={() => !disabled && onSetMax(`${ethBalance}`)}
weight="bold"
>
Send max

View File

@ -1,4 +1,4 @@
import { GenericModal, ModalFooterConfirmation } from '@gnosis.pm/safe-react-components'
import { GenericModal, ModalFooterConfirmation, Text } from '@gnosis.pm/safe-react-components'
import { makeStyles } from '@material-ui/core/styles'
import TableContainer from '@material-ui/core/TableContainer'
import cn from 'classnames'
@ -83,10 +83,10 @@ const Advanced: React.FC = () => {
{/* Nonce */}
<Block className={classes.container}>
<Heading tag="h2">Safe Nonce</Heading>
<Paragraph>
<Text size="md">
For security reasons, transactions made with the Safe need to be executed in order. The nonce shows you which
transaction was executed most recently. You can find the nonce for a transaction in the transaction details.
</Paragraph>
</Text>
<Paragraph className={classes.ownersText} size="lg">
Current Nonce: <Bold>{nonce}</Bold>
</Paragraph>

View File

@ -19,6 +19,7 @@ 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/routes/safe/store/selectors'
import { SafeRecordProps } from '../../../../../../store/models/safe'
export const ADD_OWNER_NAME_INPUT_TEST_ID = 'add-owner-name-input'
export const ADD_OWNER_ADDRESS_INPUT_TEST_ID = 'add-owner-address-testid'
@ -34,7 +35,7 @@ const OwnerForm = ({ classes, onClose, onSubmit }) => {
const handleSubmit = (values) => {
onSubmit(values)
}
const owners = useSelector(safeOwnersSelector)
const owners = (useSelector(safeOwnersSelector) as unknown) as SafeRecordProps['owners']
const ownerDoesntExist = uniqueAddress(owners.map((o) => o.address))
return (

View File

@ -26,9 +26,8 @@ import Paragraph from 'src/components/layout/Paragraph'
import Row from 'src/components/layout/Row'
import Span from 'src/components/layout/Span'
import { getAddressBook } from 'src/logic/addressBook/store/selectors'
import { safeNeedsUpdate } from 'src/logic/safe/utils/safeVersion'
import { grantedSelector } from 'src/routes/safe/container/selector'
import { safeOwnersSelector } from 'src/routes/safe/store/selectors'
import { safeOwnersSelector, safeNeedsUpdateSelector } from 'src/routes/safe/store/selectors'
export const OWNERS_SETTINGS_TAB_TEST_ID = 'owner-settings-tab'
@ -43,7 +42,7 @@ const Settings: React.FC = () => {
const classes = useStyles()
const [state, setState] = useState(INITIAL_STATE)
const owners = useSelector(safeOwnersSelector)
const needsUpdate = useSelector(safeNeedsUpdate)
const needsUpdate = useSelector(safeNeedsUpdateSelector)
const granted = useSelector(grantedSelector)
const addressBook = useSelector(getAddressBook)

View File

@ -27,7 +27,7 @@ export const useFetchTokens = (): void => {
if (COLLECTIBLES_LOCATION_REGEX.test(location.pathname)) {
batch(() => {
dispatch(fetchCollectibles()).then(() => {
dispatch<any>(fetchCollectibles()).then(() => {
dispatch(activateAssetsByBalance(address))
})
})

View File

@ -15,7 +15,7 @@ export const useLoadSafe = (safeAddress) => {
useEffect(() => {
const fetchData = () => {
if (safeAddress) {
dispatch(fetchLatestMasterContractVersion())
dispatch<any>(fetchLatestMasterContractVersion())
.then(() => {
dispatch(fetchSafe(safeAddress))
return dispatch(fetchSafeTokens(safeAddress))

View File

@ -1,4 +1,4 @@
import { Map } from 'immutable'
import { List, Map } from 'immutable'
import { createSelector } from 'reselect'
import { tokensSelector } from 'src/logic/tokens/store/selectors'
@ -7,12 +7,13 @@ import { isUserOwner } from 'src/logic/wallets/ethAddresses'
import { userAccountSelector } from 'src/logic/wallets/store/selectors'
import { safeActiveTokensSelector, safeBalancesSelector, safeSelector } from 'src/routes/safe/store/selectors'
import { Token } from 'src/logic/tokens/store/model/token'
export const grantedSelector = createSelector(userAccountSelector, safeSelector, (userAccount, safe) =>
isUserOwner(safe, userAccount),
)
const safeEthAsTokenSelector = createSelector(safeSelector, (safe) => {
const safeEthAsTokenSelector = createSelector(safeSelector, (safe): Token | undefined => {
if (!safe) {
return undefined
}
@ -25,8 +26,8 @@ export const extendedSafeTokensSelector = createSelector(
safeBalancesSelector,
tokensSelector,
safeEthAsTokenSelector,
(safeTokens, balances, tokensList, ethAsToken) => {
const extendedTokens = Map().withMutations((map) => {
(safeTokens, balances, tokensList, ethAsToken): List<Token> => {
const extendedTokens = Map<string, Token>().withMutations((map) => {
safeTokens.forEach((tokenAddress) => {
const baseToken = tokensList.get(tokenAddress)
const tokenBalance = balances.get(tokenAddress)

View File

@ -89,9 +89,9 @@ interface CreateTransaction extends WithSnackbarProps {
origin?: string
safeAddress: string
to: string
txData: string
txData?: string
txNonce?: number | string
valueInWei: string
valueInWei: number | string
}
const createTransaction = ({
@ -166,7 +166,10 @@ const createTransaction = ({
await saveTxToHistory({ ...txArgs, signature, origin })
showSnackbar(notificationsQueue.afterExecution.moreConfirmationsNeeded, enqueueSnackbar, closeSnackbar)
dispatch(fetchTransactions(safeAddress))
dispatch({
type: 'FETCH_TRANSACTION',
payload: fetchTransactions(safeAddress),
})
return
}
}
@ -183,7 +186,7 @@ const createTransaction = ({
const txToMock: TxToMock = {
...txArgs,
confirmations: [], // this is used to determine if a tx is pending or not. See `calculateTransactionStatus` helper
value: txArgs.valueInWei,
value: `${txArgs.valueInWei}`,
safeTxHash: generateSafeTxHash(safeAddress, txArgs),
}
const mockedTx = await mockTransaction(txToMock, safeAddress, state)
@ -209,7 +212,10 @@ const createTransaction = ({
state,
),
])
dispatch(fetchTransactions(safeAddress))
dispatch({
type: 'FETCH_TRANSACTIONS',
payload: fetchTransactions(safeAddress),
})
} catch (e) {
removeTxFromStore(mockedTx, safeAddress, dispatch, state)
}
@ -255,8 +261,7 @@ const createTransaction = ({
dispatch,
state,
)
dispatch(fetchTransactions(safeAddress))
;(await fetchTransactions(safeAddress))(dispatch)
return receipt.transactionHash
})

View File

@ -7,10 +7,11 @@ import { loadOutgoingTransactions } from './loadOutgoingTransactions'
import { addOrUpdateCancellationTransactions } from 'src/routes/safe/store/actions/transactions/addOrUpdateCancellationTransactions'
import { addOrUpdateTransactions } from 'src/routes/safe/store/actions/transactions/addOrUpdateTransactions'
import { Dispatch } from 'redux'
const noFunc = () => {}
export default (safeAddress: string) => async (dispatch) => {
export default (safeAddress: string) => async (dispatch: Dispatch): Promise<void> => {
const transactions = await loadOutgoingTransactions(safeAddress)
if (transactions) {

View File

@ -93,5 +93,5 @@ export type TxArgs = {
sender?: string
sigs: string
to: string
valueInWei: string
valueInWei: number | string
}

View File

@ -153,13 +153,16 @@ export const safeBlacklistedTokensSelector = createSelector(safeSelector, (safe)
return safe.blacklistedTokens
})
export const safeBlacklistedAssetsSelector = createSelector(safeSelector, (safe) => {
if (!safe) {
return List()
}
export const safeBlacklistedAssetsSelector = createSelector(
safeSelector,
(safe): Set<string> => {
if (!safe) {
return Set()
}
return safe.blacklistedAssets
})
return safe.blacklistedAssets
},
)
export const safeActiveAssetsSelectorBySafe = (safeAddress, safes) => safes.get(safeAddress).get('activeAssets')
@ -179,9 +182,9 @@ export const safeBalancesSelector = createSelector(
const baseSafe = makeSafe()
export const safeFieldSelector = (field: keyof SafeRecordProps) => (
export const safeFieldSelector = <K extends keyof SafeRecordProps>(field: K) => (
safe: SafeRecord,
): SafeRecord[keyof SafeRecordProps] | null => (safe ? safe.get(field, baseSafe.get(field)) : null)
): SafeRecordProps[K] | null => (safe ? safe.get(field, baseSafe.get(field)) : null)
export const safeNameSelector = createSelector(safeSelector, safeFieldSelector('name'))

View File

@ -1,3 +1,4 @@
import { Map } from 'immutable'
import { connectRouter, routerMiddleware } from 'connected-react-router'
import { createHashHistory } from 'history'
import { applyMiddleware, combineReducers, compose, createStore, CombinedState } from 'redux'
@ -31,6 +32,7 @@ import safe, { SAFE_REDUCER_ID } from 'src/routes/safe/store/reducer/safe'
import transactions, { TRANSACTIONS_REDUCER_ID } from 'src/routes/safe/store/reducer/transactions'
import { ProviderRecord } from '../logic/wallets/store/model/provider'
import { SafeRecordProps } from '../routes/safe/store/models/safe'
import { Token } from '../logic/tokens/store/model/token'
export const history = createHashHistory({ hashType: 'slash' })
@ -66,11 +68,11 @@ const reducers = combineReducers({
})
export type GnosisState = CombinedState<{
[PROVIDER_REDUCER_ID]: ProviderRecord
[SAFE_REDUCER_ID]: SafeRecordProps
[PROVIDER_REDUCER_ID]?: ProviderRecord
[SAFE_REDUCER_ID]?: SafeRecordProps
// [NFT_ASSETS_REDUCER_ID]: nftAssetReducer,
// [NFT_TOKENS_REDUCER_ID]: nftTokensReducer,
// [TOKEN_REDUCER_ID]: tokens,
[TOKEN_REDUCER_ID]?: Map<string, Token>
// [TRANSACTIONS_REDUCER_ID]: transactions,
// [CANCELLATION_TRANSACTIONS_REDUCER_ID]: cancellationTransactions,
// [INCOMING_TRANSACTIONS_REDUCER_ID]: incomingTransactions,

877
yarn.lock

File diff suppressed because it is too large Load Diff