diff --git a/src/logic/safe/store/actions/addSafe.ts b/src/logic/safe/store/actions/addSafe.ts index a2f5bd0d..0317a22f 100644 --- a/src/logic/safe/store/actions/addSafe.ts +++ b/src/logic/safe/store/actions/addSafe.ts @@ -6,9 +6,13 @@ import { makeOwner } from 'src/logic/safe/store/models/owner' import { safesListSelector } from 'src/logic/safe/store/selectors' +import { Dispatch } from 'redux' +import { AppReduxState } from 'src/store' +import { SafeOwner, SafeRecordProps } from 'src/logic/safe/store/models/safe' + export const ADD_SAFE = 'ADD_SAFE' -export const buildOwnersFrom = (names, addresses) => { +export const buildOwnersFrom = (names: string[], addresses: string[]): List => { const owners = names.map((name, index) => makeOwner({ name, address: addresses[index] })) return List(owners) @@ -18,7 +22,7 @@ export const addSafe = createAction(ADD_SAFE, (safe) => ({ safe, })) -const saveSafe = (safe: any) => (dispatch, getState) => { +const saveSafe = (safe: SafeRecordProps) => (dispatch: Dispatch, getState: () => AppReduxState): void => { const state = getState() const safeList = safesListSelector(state) diff --git a/src/logic/safe/store/actions/fetchSafe.ts b/src/logic/safe/store/actions/fetchSafe.ts index 2a7c82ef..bd95676e 100644 --- a/src/logic/safe/store/actions/fetchSafe.ts +++ b/src/logic/safe/store/actions/fetchSafe.ts @@ -1,5 +1,5 @@ import GnosisSafeSol from '@gnosis.pm/safe-contracts/build/contracts/GnosisSafe.json' -import { List } from 'immutable' +import { List, Set, Map } from 'immutable' import generateBatchRequests from 'src/logic/contracts/generateBatchRequests' import { getLocalSafe, getSafeName } from 'src/logic/safe/utils' @@ -13,16 +13,15 @@ import updateSafe from 'src/logic/safe/store/actions/updateSafe' import { makeOwner } from 'src/logic/safe/store/models/owner' import { checksumAddress } from 'src/utils/checksumAddress' -import { ModulePair, SafeOwner } from 'src/logic/safe/store/models/safe' -import { Dispatch } from 'redux' +import { ModulePair, SafeOwner, SafeRecordProps } from 'src/logic/safe/store/models/safe' +import { Action, Dispatch } from 'redux' import { SENTINEL_ADDRESS } from 'src/logic/contracts/safeContracts' +import { AppReduxState } from 'src/store' -const buildOwnersFrom = ( - safeOwners, - localSafe, // eslint-disable-next-line -) => - safeOwners.map((ownerAddress) => { +const buildOwnersFrom = (safeOwners: string[], localSafe: SafeRecordProps): List => { + const ownersList = safeOwners.map((ownerAddress) => { const convertedAdd = checksumAddress(ownerAddress) + if (!localSafe) { return makeOwner({ name: 'UNKNOWN', address: convertedAdd }) } @@ -38,6 +37,9 @@ const buildOwnersFrom = ( }) }) + return List(ownersList) +} + const buildModulesLinkedList = (modules: string[] | undefined, nextModule: string): Array | null => { if (modules?.length) { return modules.map((moduleAddress, index, modules) => { @@ -48,7 +50,11 @@ const buildModulesLinkedList = (modules: string[] | undefined, nextModule: strin return null } -export const buildSafe = async (safeAdd: string, safeName: string, latestMasterContractVersion?: any) => { +export const buildSafe = async ( + safeAdd: string, + safeName: string, + latestMasterContractVersion?: string, +): Promise => { const safeAddress = checksumAddress(safeAdd) const safeParams = ['getThreshold', 'nonce', 'VERSION', 'getOwners'] @@ -57,18 +63,18 @@ export const buildSafe = async (safeAdd: string, safeName: string, latestMasterC abi: GnosisSafeSol.abi, address: safeAddress, methods: safeParams, - } as any), + }), getLocalSafe(safeAddress), getBalanceInEtherOf(safeAddress), ]) const threshold = Number(thresholdStr) const nonce = Number(nonceStr) - const owners = List(buildOwnersFrom(remoteOwners, localSafe)) + const owners = buildOwnersFrom(remoteOwners, localSafe) const needsUpdate = safeNeedsUpdate(currentVersion, latestMasterContractVersion) const featuresEnabled = enabledFeatures(currentVersion) - const safe = { + return { address: safeAddress, name: safeName, threshold, @@ -78,9 +84,14 @@ export const buildSafe = async (safeAdd: string, safeName: string, latestMasterC currentVersion, needsUpdate, featuresEnabled, + balances: Map(), + latestIncomingTxBlock: null, + activeAssets: Set(), + activeTokens: Set(), + blacklistedAssets: Set(), + blacklistedTokens: Set(), + modules: null, } - - return safe } export const checkAndUpdateSafe = (safeAdd: string) => async (dispatch: Dispatch): Promise => { @@ -98,7 +109,7 @@ export const checkAndUpdateSafe = (safeAdd: string) => async (dispatch: Dispatch abi: GnosisSafeSol.abi, address: safeAddress, methods: safeParams, - } as any), + }), getLocalSafe(safeAddress), ]) @@ -139,8 +150,10 @@ export const checkAndUpdateSafe = (safeAdd: string) => async (dispatch: Dispatch } } -// eslint-disable-next-line consistent-return -export default (safeAdd: string) => async (dispatch, getState) => { +export default (safeAdd: string) => async ( + dispatch: Dispatch, + getState: () => AppReduxState, +): Promise => { try { const safeAddress = checksumAddress(safeAdd) const safeName = (await getSafeName(safeAddress)) || 'LOADED SAFE' diff --git a/src/logic/safe/store/actions/loadDefaultSafe.ts b/src/logic/safe/store/actions/loadDefaultSafe.ts index 8934acb7..348f47fc 100644 --- a/src/logic/safe/store/actions/loadDefaultSafe.ts +++ b/src/logic/safe/store/actions/loadDefaultSafe.ts @@ -3,8 +3,9 @@ import setDefaultSafe from './setDefaultSafe' import { getDefaultSafe } from 'src/logic/safe/utils' import { checksumAddress } from 'src/utils/checksumAddress' +import { Dispatch } from 'redux' -const loadDefaultSafe = () => async (dispatch) => { +const loadDefaultSafe = () => async (dispatch: Dispatch): Promise => { try { const defaultSafe = await getDefaultSafe() const checksumed = defaultSafe && defaultSafe.length > 0 ? checksumAddress(defaultSafe) : defaultSafe diff --git a/src/logic/safe/store/actions/loadSafesFromStorage.ts b/src/logic/safe/store/actions/loadSafesFromStorage.ts index e3100d14..e4a36dd9 100644 --- a/src/logic/safe/store/actions/loadSafesFromStorage.ts +++ b/src/logic/safe/store/actions/loadSafesFromStorage.ts @@ -5,8 +5,9 @@ import { SAFES_KEY } from 'src/logic/safe/utils' import { buildSafe } from 'src/logic/safe/store/reducer/safe' import { loadFromStorage } from 'src/utils/storage' +import { Dispatch } from 'redux' -const loadSafesFromStorage = () => async (dispatch) => { +const loadSafesFromStorage = () => async (dispatch: Dispatch): Promise => { try { const safes = await loadFromStorage(SAFES_KEY) diff --git a/src/logic/safe/store/actions/setDefaultSafe.ts b/src/logic/safe/store/actions/setDefaultSafe.ts index e45f7328..bb71d554 100644 --- a/src/logic/safe/store/actions/setDefaultSafe.ts +++ b/src/logic/safe/store/actions/setDefaultSafe.ts @@ -1,8 +1,9 @@ import { createAction } from 'redux-actions' +import { AnyAction } from 'redux' export const SET_DEFAULT_SAFE = 'SET_DEFAULT_SAFE' -export type SetDefaultSafe = (safe: string) => void +export type SetDefaultSafe = (safe: string) => AnyAction const setDefaultSafe: SetDefaultSafe = createAction(SET_DEFAULT_SAFE) diff --git a/src/logic/safe/store/reducer/safe.ts b/src/logic/safe/store/reducer/safe.ts index 982db4c0..7a1e9b4b 100644 --- a/src/logic/safe/store/reducer/safe.ts +++ b/src/logic/safe/store/reducer/safe.ts @@ -12,14 +12,14 @@ import { SET_DEFAULT_SAFE } from 'src/logic/safe/store/actions/setDefaultSafe' import { SET_LATEST_MASTER_CONTRACT_VERSION } from 'src/logic/safe/store/actions/setLatestMasterContractVersion' import { UPDATE_SAFE } from 'src/logic/safe/store/actions/updateSafe' import { makeOwner } from 'src/logic/safe/store/models/owner' -import makeSafe from 'src/logic/safe/store/models/safe' +import makeSafe, { SafeRecordProps } from 'src/logic/safe/store/models/safe' import { checksumAddress } from 'src/utils/checksumAddress' import { SafeReducerMap } from 'src/routes/safe/store/reducer/types/safe' export const SAFE_REDUCER_ID = 'safes' export const DEFAULT_SAFE_INITIAL_STATE = 'NOT_ASKED' -export const buildSafe = (storedSafe) => { +export const buildSafe = (storedSafe: SafeRecordProps): SafeRecordProps => { const names = storedSafe.owners.map((owner) => owner.name) const addresses = storedSafe.owners.map((owner) => checksumAddress(owner.address)) const owners = buildOwnersFrom(Array.from(names), Array.from(addresses)) @@ -29,7 +29,7 @@ export const buildSafe = (storedSafe) => { const blacklistedAssets = Set(storedSafe.blacklistedAssets) const balances = Map(storedSafe.balances) - const safe = { + return { ...storedSafe, owners, balances, @@ -37,9 +37,9 @@ export const buildSafe = (storedSafe) => { blacklistedTokens, activeAssets, blacklistedAssets, + latestIncomingTxBlock: null, + modules: null, } - - return safe } export default handleActions( diff --git a/src/logic/safe/utils/safeStorage.ts b/src/logic/safe/utils/safeStorage.ts index 868bf207..c782db82 100644 --- a/src/logic/safe/utils/safeStorage.ts +++ b/src/logic/safe/utils/safeStorage.ts @@ -1,10 +1,11 @@ import { loadFromStorage, saveToStorage } from 'src/utils/storage' +import { SafeRecordProps } from 'src/logic/safe/store/models/safe' export const SAFES_KEY = 'SAFES' export const TX_KEY = 'TX' export const DEFAULT_SAFE_KEY = 'DEFAULT_SAFE' -export const getSafeName = async (safeAddress) => { +export const getSafeName = async (safeAddress: string): Promise => { const safes = await loadFromStorage(SAFES_KEY) if (!safes) { return undefined @@ -22,9 +23,9 @@ export const saveSafes = async (safes) => { } } -export const getLocalSafe = async (safeAddress) => { +export const getLocalSafe = async (safeAddress: string): Promise => { const storedSafes = (await loadFromStorage(SAFES_KEY)) || {} - return storedSafes[safeAddress] + return storedSafes[safeAddress] || null } export const getDefaultSafe = async (): Promise => { @@ -33,7 +34,7 @@ export const getDefaultSafe = async (): Promise => { return defaultSafe || '' } -export const saveDefaultSafe = async (safeAddress) => { +export const saveDefaultSafe = async (safeAddress: string): Promise => { try { await saveToStorage(DEFAULT_SAFE_KEY, safeAddress) } catch (err) { diff --git a/src/routes/load/container/Load.tsx b/src/routes/load/container/Load.tsx index 6906c62c..689f460e 100644 --- a/src/routes/load/container/Load.tsx +++ b/src/routes/load/container/Load.tsx @@ -1,12 +1,9 @@ import * as React from 'react' -import { connect } from 'react-redux' +import { useDispatch, useSelector } from 'react-redux' -import Layout from '../components/Layout' +import Layout from 'src/routes/load/components/Layout' import { FIELD_LOAD_ADDRESS, FIELD_LOAD_NAME } from '../components/fields' -import actions from './actions' -import selector from './selector' - import Page from 'src/components/layout/Page' import { getGnosisSafeInstanceAt } from 'src/logic/contracts/safeContracts' import { SAFES_KEY, saveSafes } from 'src/logic/safe/utils' @@ -15,16 +12,17 @@ import { SAFELIST_ADDRESS } from 'src/routes/routes' import { buildSafe } from 'src/logic/safe/store/actions/fetchSafe' import { history } from 'src/store' import { loadFromStorage } from 'src/utils/storage' -import { Dispatch } from 'redux' -import { SafeOwner } from '../../../logic/safe/store/models/safe' +import { SafeOwner, SafeRecordProps } from 'src/logic/safe/store/models/safe' import { List } from 'immutable' import { checksumAddress } from 'src/utils/checksumAddress' +import { addSafe } from 'src/logic/safe/store/actions/addSafe' +import { networkSelector, providerNameSelector, userAccountSelector } from 'src/logic/wallets/store/selectors' export const loadSafe = async ( safeName: string, safeAddress: string, owners: List, - addSafe: Dispatch, + addSafe: (safe: SafeRecordProps) => void, ): Promise => { const safeProps = await buildSafe(safeAddress, safeName) safeProps.owners = owners @@ -37,20 +35,21 @@ export const loadSafe = async ( await addSafe(safeProps) } -interface LoadProps { - addSafe: Dispatch - network: string - provider?: string - userAddress: string -} - export interface LoadFormValues { name: string address: string threshold: string } -const Load = ({ addSafe, network, provider, userAddress }: LoadProps): React.ReactElement => { +const Load = (): React.ReactElement => { + const dispatch = useDispatch() + const provider = useSelector(providerNameSelector) + const network = useSelector(networkSelector) + const userAddress = useSelector(userAccountSelector) + + const addSafeHandler = (safe: SafeRecordProps) => { + dispatch(addSafe(safe)) + } const onLoadSafeSubmit = async (values: LoadFormValues) => { let safeAddress = values[FIELD_LOAD_ADDRESS] // TODO: review this check. It doesn't seems to be necessary at this point @@ -68,7 +67,7 @@ const Load = ({ addSafe, network, provider, userAddress }: LoadProps): React.Rea const ownerAddresses = await gnosisSafe.methods.getOwners().call() const owners = getOwnersFrom(ownerNames, ownerAddresses.slice().sort()) - await loadSafe(safeName, safeAddress, owners, addSafe) + await loadSafe(safeName, safeAddress, owners, addSafeHandler) const url = `${SAFELIST_ADDRESS}/${safeAddress}/balances` history.push(url) @@ -79,9 +78,9 @@ const Load = ({ addSafe, network, provider, userAddress }: LoadProps): React.Rea return ( - + ) } -export default connect(selector, actions)(Load) +export default Load diff --git a/src/routes/load/container/actions.ts b/src/routes/load/container/actions.ts deleted file mode 100644 index 918dbf44..00000000 --- a/src/routes/load/container/actions.ts +++ /dev/null @@ -1,5 +0,0 @@ -import addSafe from 'src/logic/safe/store/actions/addSafe' - -export default { - addSafe, -} diff --git a/src/routes/load/container/selector.ts b/src/routes/load/container/selector.ts deleted file mode 100644 index cce0e6bf..00000000 --- a/src/routes/load/container/selector.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { createStructuredSelector } from 'reselect' - -import { networkSelector, providerNameSelector, userAccountSelector } from 'src/logic/wallets/store/selectors' - -const structuredSelector = createStructuredSelector({ - provider: providerNameSelector, - network: networkSelector, - userAddress: userAccountSelector, -}) - -export default structuredSelector