* Wip * fetchTransactions fix * fix p > div > p nesting, fix displaying undefined as currency * fix duplicate import
This commit is contained in:
parent
9b32cc9dc1
commit
f1d1b78531
|
@ -2,7 +2,7 @@
|
|||
import React from 'react'
|
||||
import { withStyles } from '@material-ui/core/styles'
|
||||
import Block from '~/components/layout/Block'
|
||||
import Paragraph from '~/components/layout/Paragraph'
|
||||
import Span from '~/components/layout/Span'
|
||||
import CopyBtn from '~/components/CopyBtn'
|
||||
import EtherscanBtn from '~/components/EtherscanBtn'
|
||||
import { shortVersionOf } from '~/logic/wallets/ethAddresses'
|
||||
|
@ -19,9 +19,9 @@ const EtherscanLink = ({
|
|||
type, value, cut, classes,
|
||||
}: EtherscanLinkProps) => (
|
||||
<Block className={classes.etherscanLink}>
|
||||
<Paragraph size="md" noMargin>
|
||||
<Span size="md">
|
||||
{cut ? shortVersionOf(value, cut) : value}
|
||||
</Paragraph>
|
||||
</Span>
|
||||
<CopyBtn content={value} />
|
||||
<EtherscanBtn type={type} value={value} />
|
||||
</Block>
|
||||
|
|
|
@ -1,11 +1,8 @@
|
|||
// @flow
|
||||
import { List, Map } from 'immutable'
|
||||
import { type Owner } from '~/routes/safe/store/models/owner'
|
||||
import { loadFromStorage, saveToStorage, removeFromStorage } from '~/utils/storage'
|
||||
import { loadFromStorage, saveToStorage } from '~/utils/storage'
|
||||
|
||||
export const SAFES_KEY = 'SAFES'
|
||||
export const TX_KEY = 'TX'
|
||||
export const OWNERS_KEY = 'OWNERS'
|
||||
export const DEFAULT_SAFE_KEY = 'DEFAULT_SAFE'
|
||||
|
||||
export const getSafeName = async (safeAddress: string) => {
|
||||
|
@ -26,19 +23,9 @@ export const saveSafes = async (safes: Object) => {
|
|||
}
|
||||
}
|
||||
|
||||
export const setOwners = async (safeAddress: string, owners: List<Owner>) => {
|
||||
try {
|
||||
const ownersAsMap = Map(owners.map((owner: Owner) => [owner.address.toLowerCase(), owner.name]))
|
||||
await saveToStorage(`${OWNERS_KEY}-${safeAddress}`, ownersAsMap)
|
||||
} catch (err) {
|
||||
console.error('Error storing owners in localstorage', err)
|
||||
}
|
||||
}
|
||||
|
||||
export const getOwners = async (safeAddress: string): Promise<Map<string, string>> => {
|
||||
const data: Object = await loadFromStorage(`${OWNERS_KEY}-${safeAddress}`)
|
||||
|
||||
return data ? Map(data) : Map()
|
||||
export const getLocalSafe = async (safeAddress: string) => {
|
||||
const storedSafes = (await loadFromStorage(SAFES_KEY)) || {}
|
||||
return storedSafes[safeAddress]
|
||||
}
|
||||
|
||||
export const getDefaultSafe = async (): Promise<string> => {
|
||||
|
@ -55,12 +42,3 @@ export const saveDefaultSafe = async (safeAddress: string): Promise<void> => {
|
|||
console.error('Error saving default Safe to storage: ', err)
|
||||
}
|
||||
}
|
||||
|
||||
export const removeOwners = async (safeAddress: string): Promise<void> => {
|
||||
try {
|
||||
await removeFromStorage(`${OWNERS_KEY}-${safeAddress}`)
|
||||
} catch (err) {
|
||||
// eslint-disable-next-line
|
||||
console.error('Error removing owners from localstorage: ', err)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,6 +29,10 @@ const getTokenPriceInCurrency = (
|
|||
currencySelected: typeof AVAILABLE_CURRENCIES,
|
||||
currencyValues: List<BalanceCurrencyType>,
|
||||
): string => {
|
||||
if (!currencySelected) {
|
||||
return ''
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
for (const tokenPriceIterator of currencyValues) {
|
||||
const {
|
||||
|
@ -115,6 +119,7 @@ export const generateColumns = () => {
|
|||
label: 'Value',
|
||||
custom: false,
|
||||
static: true,
|
||||
disablePadding: false,
|
||||
style: {
|
||||
fontSize: '11px',
|
||||
color: '#5d6d74',
|
||||
|
|
|
@ -4,7 +4,6 @@ import { makeStyles } from '@material-ui/core/styles'
|
|||
import type { IncomingTransaction } from '~/routes/safe/store/models/incomingTransaction'
|
||||
import Bold from '~/components/layout/Bold'
|
||||
import EtherscanLink from '~/components/EtherscanLink'
|
||||
import Paragraph from '~/components/layout/Paragraph'
|
||||
import Block from '~/components/layout/Block'
|
||||
import { md, lg } from '~/theme/variables'
|
||||
import { getIncomingTxAmount } from '~/routes/safe/components/Transactions/TxsTable/columns'
|
||||
|
@ -28,7 +27,7 @@ type TransferDescProps = {
|
|||
}
|
||||
|
||||
const TransferDescription = ({ value = '', from }: TransferDescProps) => (
|
||||
<Paragraph noMargin data-testid={TRANSACTIONS_DESC_INCOMING_TEST_ID}>
|
||||
<Block data-testid={TRANSACTIONS_DESC_INCOMING_TEST_ID}>
|
||||
<Bold>
|
||||
Received
|
||||
{' '}
|
||||
|
@ -38,7 +37,7 @@ const TransferDescription = ({ value = '', from }: TransferDescProps) => (
|
|||
</Bold>
|
||||
<br />
|
||||
<EtherscanLink type="address" value={from} />
|
||||
</Paragraph>
|
||||
</Block>
|
||||
)
|
||||
|
||||
const IncomingTxDescription = ({ tx }: Props) => {
|
||||
|
|
|
@ -1,25 +1,35 @@
|
|||
// @flow
|
||||
import type { Dispatch as ReduxDispatch } from 'redux'
|
||||
import { List, Map } from 'immutable'
|
||||
import { List } from 'immutable'
|
||||
import { type GlobalState } from '~/store/index'
|
||||
import { makeOwner } from '~/routes/safe/store/models/owner'
|
||||
import type { SafeProps } from '~/routes/safe/store/models/safe'
|
||||
import addSafe from '~/routes/safe/store/actions/addSafe'
|
||||
import { getOwners, getSafeName, SAFES_KEY } from '~/logic/safe/utils'
|
||||
import { getSafeName, getLocalSafe } from '~/logic/safe/utils'
|
||||
import { getGnosisSafeInstanceAt } from '~/logic/contracts/safeContracts'
|
||||
import { getBalanceInEtherOf } from '~/logic/wallets/getWeb3'
|
||||
import { loadFromStorage } from '~/utils/storage'
|
||||
import { sameAddress } from '~/logic/wallets/ethAddresses'
|
||||
import removeSafeOwner from '~/routes/safe/store/actions/removeSafeOwner'
|
||||
import addSafeOwner from '~/routes/safe/store/actions/addSafeOwner'
|
||||
import updateSafeThreshold from '~/routes/safe/store/actions/updateSafeThreshold'
|
||||
import { sameAddress } from '~/logic/wallets/ethAddresses'
|
||||
|
||||
const buildOwnersFrom = (
|
||||
safeOwners: string[],
|
||||
storedOwners: Map<string, string>, // eslint-disable-next-line
|
||||
localSafe: SafeProps | {}, // eslint-disable-next-line
|
||||
) => safeOwners.map((ownerAddress: string) => {
|
||||
const ownerName = storedOwners.get(ownerAddress.toLowerCase()) || 'UNKNOWN'
|
||||
return makeOwner({ name: ownerName, address: ownerAddress })
|
||||
if (!localSafe) {
|
||||
return makeOwner({ name: 'UNKNOWN', address: ownerAddress })
|
||||
}
|
||||
|
||||
const storedOwner = localSafe.owners.find(({ address }) => sameAddress(address, ownerAddress))
|
||||
if (!storedOwner) {
|
||||
return makeOwner({ name: 'UNKNOWN', address: ownerAddress })
|
||||
}
|
||||
|
||||
return makeOwner({
|
||||
name: storedOwner.name || 'UNKNOWN',
|
||||
address: ownerAddress,
|
||||
})
|
||||
})
|
||||
|
||||
export const buildSafe = async (safeAddress: string, safeName: string) => {
|
||||
|
@ -28,7 +38,12 @@ export const buildSafe = async (safeAddress: string, safeName: string) => {
|
|||
|
||||
const threshold = Number(await gnosisSafe.getThreshold())
|
||||
const nonce = Number(await gnosisSafe.nonce())
|
||||
const owners = List(buildOwnersFrom(await gnosisSafe.getOwners(), await getOwners(safeAddress)))
|
||||
const owners = List(
|
||||
buildOwnersFrom(
|
||||
await gnosisSafe.getOwners(),
|
||||
await getLocalSafe(safeAddress),
|
||||
),
|
||||
)
|
||||
|
||||
const safe: SafeProps = {
|
||||
address: safeAddress,
|
||||
|
@ -42,14 +57,14 @@ export const buildSafe = async (safeAddress: string, safeName: string) => {
|
|||
return safe
|
||||
}
|
||||
|
||||
const getLocalSafe = async (safeAddress: string) => {
|
||||
const storedSafes = (await loadFromStorage(SAFES_KEY)) || {}
|
||||
return storedSafes[safeAddress]
|
||||
}
|
||||
|
||||
export const checkAndUpdateSafe = (safeAddress: string) => async (dispatch: ReduxDispatch<GlobalState>) => {
|
||||
export const checkAndUpdateSafe = (safeAddress: string) => async (
|
||||
dispatch: ReduxDispatch<*>,
|
||||
) => {
|
||||
// Check if the owner's safe did change and update them
|
||||
const [gnosisSafe, localSafe] = await Promise.all([getGnosisSafeInstanceAt(safeAddress), getLocalSafe(safeAddress)])
|
||||
const [gnosisSafe, localSafe] = await Promise.all([
|
||||
getGnosisSafeInstanceAt(safeAddress),
|
||||
getLocalSafe(safeAddress),
|
||||
])
|
||||
|
||||
const remoteOwners = await gnosisSafe.getOwners()
|
||||
// Converts from [ { address, ownerName} ] to address array
|
||||
|
@ -59,8 +74,9 @@ export const checkAndUpdateSafe = (safeAddress: string) => async (dispatch: Redu
|
|||
const threshold = await gnosisSafe.getThreshold()
|
||||
localSafe.threshold = threshold.toNumber()
|
||||
|
||||
dispatch(updateSafeThreshold({ safeAddress, threshold: threshold.toNumber() }))
|
||||
|
||||
dispatch(
|
||||
updateSafeThreshold({ safeAddress, threshold: threshold.toNumber() }),
|
||||
)
|
||||
// If the remote owners does not contain a local address, we remove that local owner
|
||||
localOwners.forEach((localAddress) => {
|
||||
const remoteOwnerIndex = remoteOwners.findIndex((remoteAddress) => sameAddress(remoteAddress, localAddress))
|
||||
|
@ -73,13 +89,21 @@ export const checkAndUpdateSafe = (safeAddress: string) => async (dispatch: Redu
|
|||
remoteOwners.forEach((remoteAddress) => {
|
||||
const localOwnerIndex = localOwners.findIndex((localAddress) => sameAddress(remoteAddress, localAddress))
|
||||
if (localOwnerIndex === -1) {
|
||||
dispatch(addSafeOwner({ safeAddress, ownerAddress: remoteAddress, ownerName: 'UNKNOWN' }))
|
||||
dispatch(
|
||||
addSafeOwner({
|
||||
safeAddress,
|
||||
ownerAddress: remoteAddress,
|
||||
ownerName: 'UNKNOWN',
|
||||
}),
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// eslint-disable-next-line consistent-return
|
||||
export default (safeAddress: string) => async (dispatch: ReduxDispatch<GlobalState>) => {
|
||||
export default (safeAddress: string) => async (
|
||||
dispatch: ReduxDispatch<GlobalState>,
|
||||
) => {
|
||||
try {
|
||||
const safeName = (await getSafeName(safeAddress)) || 'LOADED SAFE'
|
||||
const safeProps: SafeProps = await buildSafe(safeAddress, safeName)
|
||||
|
@ -87,7 +111,7 @@ export default (safeAddress: string) => async (dispatch: ReduxDispatch<GlobalSta
|
|||
dispatch(addSafe(safeProps))
|
||||
} catch (err) {
|
||||
// eslint-disable-next-line
|
||||
console.error('Error while updating Safe information: ', err)
|
||||
console.error("Error while updating Safe information: ", err)
|
||||
|
||||
return Promise.resolve()
|
||||
}
|
||||
|
|
|
@ -3,23 +3,23 @@ import { List, Map } from 'immutable'
|
|||
import axios from 'axios'
|
||||
import bn from 'bignumber.js'
|
||||
import type { Dispatch as ReduxDispatch } from 'redux'
|
||||
import { type GlobalState } from '~/store/index'
|
||||
import { type GlobalState } from '~/store'
|
||||
import { makeOwner } from '~/routes/safe/store/models/owner'
|
||||
import { makeTransaction, type Transaction } from '~/routes/safe/store/models/transaction'
|
||||
import { makeIncomingTransaction, type IncomingTransaction } from '~/routes/safe/store/models/incomingTransaction'
|
||||
import { makeConfirmation } from '~/routes/safe/store/models/confirmation'
|
||||
import { buildTxServiceUrl, type TxServiceType } from '~/logic/safe/transactions/txHistory'
|
||||
import { buildIncomingTxServiceUrl } from '~/logic/safe/transactions/incomingTxHistory'
|
||||
import { getOwners } from '~/logic/safe/utils'
|
||||
import { getWeb3 } from '~/logic/wallets/getWeb3'
|
||||
import { sameAddress, ZERO_ADDRESS } from '~/logic/wallets/ethAddresses'
|
||||
import { EMPTY_DATA } from '~/logic/wallets/ethTransactions'
|
||||
import { getLocalSafe } from '~/logic/safe/utils'
|
||||
import { addTransactions } from './addTransactions'
|
||||
import { addIncomingTransactions } from './addIncomingTransactions'
|
||||
import { getHumanFriendlyToken } from '~/logic/tokens/store/actions/fetchTokens'
|
||||
import { isTokenTransfer } from '~/logic/tokens/utils/tokenHelpers'
|
||||
import { decodeParamsFromSafeMethod } from '~/logic/contracts/methodIds'
|
||||
import { ALTERNATIVE_TOKEN_ABI } from '~/logic/tokens/utils/alternativeAbi'
|
||||
import { ZERO_ADDRESS, sameAddress } from '~/logic/wallets/ethAddresses'
|
||||
|
||||
let web3
|
||||
|
||||
|
@ -64,10 +64,19 @@ export const buildTransactionFrom = async (
|
|||
safeAddress: string,
|
||||
tx: TxServiceModel,
|
||||
) => {
|
||||
const storedOwners = await getOwners(safeAddress)
|
||||
const { owners } = await getLocalSafe(safeAddress)
|
||||
|
||||
const confirmations = List(
|
||||
tx.confirmations.map((conf: ConfirmationServiceModel) => {
|
||||
const ownerName = storedOwners.get(conf.owner.toLowerCase()) || 'UNKNOWN'
|
||||
let ownerName = 'UNKNOWN'
|
||||
|
||||
if (owners) {
|
||||
const storedOwner = owners.find((owner) => sameAddress(conf.owner, owner.address))
|
||||
|
||||
if (storedOwner) {
|
||||
ownerName = storedOwner.name
|
||||
}
|
||||
}
|
||||
|
||||
return makeConfirmation({
|
||||
owner: makeOwner({ address: conf.owner, name: ownerName }),
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// @flow
|
||||
import type { AnyAction, Store } from 'redux'
|
||||
import type { Action, Store } from 'redux'
|
||||
import { List } from 'immutable'
|
||||
import { ADD_SAFE } from '~/routes/safe/store/actions/addSafe'
|
||||
import { UPDATE_SAFE } from '~/routes/safe/store/actions/updateSafe'
|
||||
|
@ -10,15 +10,12 @@ import { REPLACE_SAFE_OWNER } from '~/routes/safe/store/actions/replaceSafeOwner
|
|||
import { EDIT_SAFE_OWNER } from '~/routes/safe/store/actions/editSafeOwner'
|
||||
import { type GlobalState } from '~/store/'
|
||||
import {
|
||||
removeOwners,
|
||||
saveDefaultSafe,
|
||||
saveSafes,
|
||||
setOwners,
|
||||
} from '~/logic/safe/utils'
|
||||
import { getActiveTokensAddressesForAllSafes, safesMapSelector } from '~/routes/safe/store/selectors'
|
||||
import { tokensSelector } from '~/logic/tokens/store/selectors'
|
||||
import type { Token } from '~/logic/tokens/store/model/token'
|
||||
import { makeOwner } from '~/routes/safe/store/models/owner'
|
||||
import { saveActiveTokens } from '~/logic/tokens/utils/tokensStorage'
|
||||
import { ACTIVATE_TOKEN_FOR_ALL_SAFES } from '~/routes/safe/store/actions/activateTokenForAllSafes'
|
||||
import { SET_DEFAULT_SAFE } from '~/routes/safe/store/actions/setDefaultSafe'
|
||||
|
@ -50,7 +47,7 @@ const recalculateActiveTokens = (state: GlobalState): void => {
|
|||
saveActiveTokens(activeTokens)
|
||||
}
|
||||
|
||||
const safeStorageMware = (store: Store<GlobalState>) => (next: Function) => async (action: AnyAction) => {
|
||||
const safeStorageMware = (store: Store<GlobalState>) => (next: Function) => async (action: Action<*>) => {
|
||||
const handledAction = next(action)
|
||||
|
||||
if (watchedActions.includes(action.type)) {
|
||||
|
@ -63,64 +60,13 @@ const safeStorageMware = (store: Store<GlobalState>) => (next: Function) => asyn
|
|||
recalculateActiveTokens(state)
|
||||
break
|
||||
}
|
||||
case ADD_SAFE: {
|
||||
const { safe } = action.payload
|
||||
setOwners(safe.address, safe.owners)
|
||||
break
|
||||
}
|
||||
case UPDATE_SAFE: {
|
||||
const { safeAddress, owners, activeTokens } = action.payload
|
||||
if (safeAddress && owners) {
|
||||
setOwners(safeAddress, owners)
|
||||
}
|
||||
const { activeTokens } = action.payload
|
||||
if (activeTokens) {
|
||||
recalculateActiveTokens(state)
|
||||
}
|
||||
break
|
||||
}
|
||||
case REMOVE_SAFE: {
|
||||
const { safeAddress } = action.payload
|
||||
await removeOwners(safeAddress)
|
||||
break
|
||||
}
|
||||
case ADD_SAFE_OWNER: {
|
||||
const { safeAddress, ownerAddress, ownerName } = action.payload
|
||||
const { owners } = safes.get(safeAddress)
|
||||
setOwners(safeAddress, owners.push(makeOwner({ address: ownerAddress, name: ownerName })))
|
||||
break
|
||||
}
|
||||
case REMOVE_SAFE_OWNER: {
|
||||
const { safeAddress, ownerAddress } = action.payload
|
||||
const { owners } = safes.get(safeAddress)
|
||||
setOwners(
|
||||
safeAddress,
|
||||
owners.filter((o) => o.address.toLowerCase() !== ownerAddress.toLowerCase()),
|
||||
)
|
||||
break
|
||||
}
|
||||
case REPLACE_SAFE_OWNER: {
|
||||
const {
|
||||
safeAddress, ownerAddress, ownerName, oldOwnerAddress,
|
||||
} = action.payload
|
||||
const { owners } = safes.get(safeAddress)
|
||||
setOwners(
|
||||
safeAddress,
|
||||
owners
|
||||
.filter((o) => o.address.toLowerCase() !== oldOwnerAddress.toLowerCase())
|
||||
.push(makeOwner({ address: ownerAddress, name: ownerName })),
|
||||
)
|
||||
break
|
||||
}
|
||||
case EDIT_SAFE_OWNER: {
|
||||
const { safeAddress, ownerAddress, ownerName } = action.payload
|
||||
const { owners } = safes.get(safeAddress)
|
||||
const ownerToUpdateIndex = owners.findIndex((o) => o.address.toLowerCase() === ownerAddress.toLowerCase())
|
||||
setOwners(
|
||||
safeAddress,
|
||||
owners.update(ownerToUpdateIndex, (owner) => owner.set('name', ownerName)),
|
||||
)
|
||||
break
|
||||
}
|
||||
case SET_DEFAULT_SAFE: {
|
||||
if (action.payload) {
|
||||
saveDefaultSafe(action.payload)
|
||||
|
|
Loading…
Reference in New Issue