(Feature) Types for safe (#1274)

* Types

* Types

* Fix SetDefaultSafe return type

* Remove unused files

Co-authored-by: Daniel Sanchez <daniel.sanchez@gnosis.pm>
Co-authored-by: Mikhail Mikheev <mmvsha73@gmail.com>
This commit is contained in:
Agustin Pane 2020-08-27 07:10:02 -03:00 committed by GitHub
parent 5573383c48
commit 9fdfd7448c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 70 additions and 66 deletions

View File

@ -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<SafeOwner> => {
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)

View File

@ -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<SafeOwner> => {
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<ModulePair> | 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<SafeRecordProps> => {
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<SafeOwner>(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<void> => {
@ -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<any>,
getState: () => AppReduxState,
): Promise<Action | void> => {
try {
const safeAddress = checksumAddress(safeAdd)
const safeName = (await getSafeName(safeAddress)) || 'LOADED SAFE'

View File

@ -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<void> => {
try {
const defaultSafe = await getDefaultSafe()
const checksumed = defaultSafe && defaultSafe.length > 0 ? checksumAddress(defaultSafe) : defaultSafe

View File

@ -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<void> => {
try {
const safes = await loadFromStorage(SAFES_KEY)

View File

@ -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)

View File

@ -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(

View File

@ -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<string | undefined> => {
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<SafeRecordProps | null> => {
const storedSafes = (await loadFromStorage(SAFES_KEY)) || {}
return storedSafes[safeAddress]
return storedSafes[safeAddress] || null
}
export const getDefaultSafe = async (): Promise<string> => {
@ -33,7 +34,7 @@ export const getDefaultSafe = async (): Promise<string> => {
return defaultSafe || ''
}
export const saveDefaultSafe = async (safeAddress) => {
export const saveDefaultSafe = async (safeAddress: string): Promise<void> => {
try {
await saveToStorage(DEFAULT_SAFE_KEY, safeAddress)
} catch (err) {

View File

@ -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<SafeOwner>,
addSafe: Dispatch<any>,
addSafe: (safe: SafeRecordProps) => void,
): Promise<void> => {
const safeProps = await buildSafe(safeAddress, safeName)
safeProps.owners = owners
@ -37,20 +35,21 @@ export const loadSafe = async (
await addSafe(safeProps)
}
interface LoadProps {
addSafe: Dispatch<any>
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 (
<Page>
<Layout network={network} onLoadSafeSubmit={onLoadSafeSubmit} provider={provider} userAddress={userAddress} />
<Layout onLoadSafeSubmit={onLoadSafeSubmit} network={network} userAddress={userAddress} provider={provider} />
</Page>
)
}
export default connect(selector, actions)(Load)
export default Load

View File

@ -1,5 +0,0 @@
import addSafe from 'src/logic/safe/store/actions/addSafe'
export default {
addSafe,
}

View File

@ -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