Refactor web3 provider notifications

This commit is contained in:
Germán Martínez 2019-09-23 12:32:46 +02:00
parent 0971e4a929
commit a581135d7f
8 changed files with 93 additions and 75 deletions

View File

@ -3,9 +3,9 @@ import * as React from 'react'
import { connect } from 'react-redux' import { connect } from 'react-redux'
import { withSnackbar } from 'notistack' import { withSnackbar } from 'notistack'
import { logComponentStack, type Info } from '~/utils/logBoundaries' import { logComponentStack, type Info } from '~/utils/logBoundaries'
import { WALLET_ERROR_MSG } from '~/logic/wallets/store/actions'
import { getProviderInfo } from '~/logic/wallets/getWeb3' import { getProviderInfo } from '~/logic/wallets/getWeb3'
import type { ProviderProps } from '~/logic/wallets/store/model/provider' import type { ProviderProps } from '~/logic/wallets/store/model/provider'
import { NOTIFICATIONS } from '~/logic/notifications'
import ProviderAccesible from './component/ProviderInfo/ProviderAccesible' import ProviderAccesible from './component/ProviderInfo/ProviderAccesible'
import UserDetails from './component/ProviderDetails/UserDetails' import UserDetails from './component/ProviderDetails/UserDetails'
import ProviderDisconnected from './component/ProviderInfo/ProviderDisconnected' import ProviderDisconnected from './component/ProviderInfo/ProviderDisconnected'
@ -14,16 +14,9 @@ import Layout from './component/Layout'
import actions, { type Actions } from './actions' import actions, { type Actions } from './actions'
import selector, { type SelectorProps } from './selector' import selector, { type SelectorProps } from './selector'
export const SUCCESS = 'success'
export const ERROR = 'error'
export const WARNING = 'warning'
export const INFO = 'info'
export type Variant = SUCCESS | ERROR | WARNING | INFO
type Props = Actions & type Props = Actions &
SelectorProps & { SelectorProps & {
enqueueSnackbar: (message: string, variant: Variant) => void, enqueueSnackbar: Function,
} }
type State = { type State = {
@ -49,7 +42,7 @@ class HeaderComponent extends React.PureComponent<Props, State> {
const { enqueueSnackbar } = this.props const { enqueueSnackbar } = this.props
this.setState({ hasError: true }) this.setState({ hasError: true })
enqueueSnackbar(WALLET_ERROR_MSG, { variant: ERROR }) enqueueSnackbar(NOTIFICATIONS.CONNECT_WALLET_ERROR_MSG.description, NOTIFICATIONS.CONNECT_WALLET_ERROR_MSG.options)
logComponentStack(error, info) logComponentStack(error, info)
} }
@ -63,16 +56,16 @@ class HeaderComponent extends React.PureComponent<Props, State> {
} }
onConnect = async () => { onConnect = async () => {
const { fetchProvider, enqueueSnackbar } = this.props const { fetchProvider, enqueueSnackbar, closeSnackbar } = this.props
clearInterval(this.providerListener) clearInterval(this.providerListener)
let currentProvider: ProviderProps = await getProviderInfo() let currentProvider: ProviderProps = await getProviderInfo()
fetchProvider(currentProvider, enqueueSnackbar) fetchProvider(currentProvider, enqueueSnackbar, closeSnackbar)
this.providerListener = setInterval(async () => { this.providerListener = setInterval(async () => {
const newProvider: ProviderProps = await getProviderInfo() const newProvider: ProviderProps = await getProviderInfo()
if (JSON.stringify(currentProvider) !== JSON.stringify(newProvider)) { if (currentProvider && JSON.stringify(currentProvider) !== JSON.stringify(newProvider)) {
fetchProvider(newProvider, enqueueSnackbar) fetchProvider(newProvider, enqueueSnackbar, closeSnackbar)
} }
currentProvider = newProvider currentProvider = newProvider
}, 2000) }, 2000)

View File

@ -35,6 +35,17 @@ const confirmationTxNotificationsQueue: NotificationsQueue = {
afterExecutionError: NOTIFICATIONS.TX_CONFIRMATION_FAILED_MSG, afterExecutionError: NOTIFICATIONS.TX_CONFIRMATION_FAILED_MSG,
} }
const cancellationTxNotificationsQueue: NotificationsQueue = {
beforeExecution: NOTIFICATIONS.SIGN_TX_MSG,
pendingExecution: {
single: NOTIFICATIONS.TX_PENDING_MSG,
multiple: NOTIFICATIONS.TX_PENDING_MORE_CONFIRMATIONS_MSG,
},
afterRejection: NOTIFICATIONS.TX_REJECTED_MSG,
afterExecution: NOTIFICATIONS.TX_EXECUTED_MSG,
afterExecutionError: NOTIFICATIONS.TX_FAILED_MSG,
}
const ownerChangeTxNotificationsQueue: NotificationsQueue = { const ownerChangeTxNotificationsQueue: NotificationsQueue = {
beforeExecution: NOTIFICATIONS.SIGN_OWNER_CHANGE_MSG, beforeExecution: NOTIFICATIONS.SIGN_OWNER_CHANGE_MSG,
pendingExecution: { pendingExecution: {
@ -54,7 +65,7 @@ const safeNameChangeNotificationsQueue: NotificationsQueue = {
}, },
afterRejection: null, afterRejection: null,
afterExecution: NOTIFICATIONS.SAFE_NAME_CHANGE_EXECUTED_MSG, afterExecution: NOTIFICATIONS.SAFE_NAME_CHANGE_EXECUTED_MSG,
afterExeCONNECT_WALLET_TXcutionError: null, afterExecutionError: null,
} }
const ownerNameChangeNotificationsQueue: NotificationsQueue = { const ownerNameChangeNotificationsQueue: NotificationsQueue = {
@ -105,6 +116,10 @@ export const getNofiticationsFromTxType = (txType: string) => {
notificationsQueue = confirmationTxNotificationsQueue notificationsQueue = confirmationTxNotificationsQueue
break break
} }
case NOTIFIED_TRANSACTIONS.CANCELLATION_TX: {
notificationsQueue = cancellationTxNotificationsQueue
break
}
case NOTIFIED_TRANSACTIONS.OWNER_CHANGE_TX: { case NOTIFIED_TRANSACTIONS.OWNER_CHANGE_TX: {
notificationsQueue = ownerChangeTxNotificationsQueue notificationsQueue = ownerChangeTxNotificationsQueue
break break

View File

@ -14,15 +14,17 @@ export type Notification = {
variant: Variant, variant: Variant,
persist: boolean, persist: boolean,
autoHideDuration?: shortDuration | longDuration, autoHideDuration?: shortDuration | longDuration,
preventDuplicate: boolean,
} }
export type Notifications = { export type Notifications = {
// Wallet Connection // Wallet Connection
CONNECT_WALLET_MSG: string, CONNECT_WALLET_MSG: Notification,
CONNECT_WALLET_READ_MODE_MSG: string, CONNECT_WALLET_READ_MODE_MSG: Notification,
WALLET_CONNECTED_MSG: string, WALLET_CONNECTED_MSG: Notification,
UNLOCK_WALLET_MSG: string, WALLET_DISCONNECTED_MSG: Notification,
CONNECT_WALLET_ERROR_MSG: string, UNLOCK_WALLET_MSG: Notification,
CONNECT_WALLET_ERROR_MSG: Notification,
// Regular/Custom Transactions // Regular/Custom Transactions
SIGN_TX_MSG: Notification, SIGN_TX_MSG: Notification,
@ -33,47 +35,47 @@ export type Notifications = {
TX_FAILED_MSG: Notification, TX_FAILED_MSG: Notification,
// Approval Transactions // Approval Transactions
TX_CONFIRMATION_PENDING_MSG: string, TX_CONFIRMATION_PENDING_MSG: Notification,
TX_CONFIRMATION_EXECUTED_MSG: string, TX_CONFIRMATION_EXECUTED_MSG: Notification,
TX_CONFIRMATION_FAILED_MSG: string, TX_CONFIRMATION_FAILED_MSG: Notification,
// Safe Name // Safe Name
SAFE_NAME_CHANGED_MSG: string, SAFE_NAME_CHANGED_MSG: Notification,
// Owner Name // Owner Name
OWNER_NAME_CHANGE_EXECUTED_MSG: string, OWNER_NAME_CHANGE_EXECUTED_MSG: Notification,
// Owners // Owners
SIGN_OWNER_CHANGE_MSG: string, SIGN_OWNER_CHANGE_MSG: Notification,
ONWER_CHANGE_PENDING_MSG: string, ONWER_CHANGE_PENDING_MSG: Notification,
ONWER_CHANGE_PENDING_MORE_CONFIRMATIONS_MSG: string, ONWER_CHANGE_PENDING_MORE_CONFIRMATIONS_MSG: Notification,
ONWER_CHANGE_REJECTED_MSG: string, ONWER_CHANGE_REJECTED_MSG: Notification,
ONWER_CHANGE_EXECUTED_MSG: string, ONWER_CHANGE_EXECUTED_MSG: Notification,
ONWER_CHANGE_FAILED_MSG: string, ONWER_CHANGE_FAILED_MSG: Notification,
// Threshold // Threshold
SIGN_THRESHOLD_CHANGE_MSG: string, SIGN_THRESHOLD_CHANGE_MSG: Notification,
THRESHOLD_CHANGE_PENDING_MSG: string, THRESHOLD_CHANGE_PENDING_MSG: Notification,
THRESHOLD_CHANGE_PENDING_MORE_CONFIRMATIONS_MSG: string, THRESHOLD_CHANGE_PENDING_MORE_CONFIRMATIONS_MSG: Notification,
THRESHOLD_CHANGE_REJECTED_MSG: string, THRESHOLD_CHANGE_REJECTED_MSG: Notification,
THRESHOLD_CHANGE_EXECUTED_MSG: string, THRESHOLD_CHANGE_EXECUTED_MSG: Notification,
THRESHOLD_CHANGE_FAILED_MSG: string, THRESHOLD_CHANGE_FAILED_MSG: Notification,
// Rinkeby version // Rinkeby version
RINKEBY_VERSION_MSG: string, RINKEBY_VERSION_MSG: Notification,
WRONG_NETWORK_RINKEBY_MSG: string, WRONG_NETWORK_RINKEBY_MSG: Notification,
WRONG_NETWOEK_MAINNET_MSG: string, WRONG_NETWOEK_MAINNET_MSG: Notification,
} }
export const NOTIFICATIONS: Notifications = { export const NOTIFICATIONS: Notifications = {
// Wallet Connection // Wallet Connection
CONNECT_WALLET_MSG: { CONNECT_WALLET_MSG: {
description: 'Please connect wallet to continue', description: 'Please connect wallet to continue',
options: { variant: WARNING, persist: true }, options: { variant: WARNING, persist: true, preventDuplicate: true },
}, },
CONNECT_WALLET_READ_MODE_MSG: { CONNECT_WALLET_READ_MODE_MSG: {
description: 'You are in read-only mode: Please connect wallet', description: 'You are in read-only mode: Please connect wallet',
options: { variant: WARNING, persist: true }, options: { variant: WARNING, persist: true, preventDuplicate: true },
}, },
WALLET_CONNECTED_MSG: { WALLET_CONNECTED_MSG: {
description: 'Wallet connected', description: 'Wallet connected',
@ -81,12 +83,19 @@ export const NOTIFICATIONS: Notifications = {
variant: SUCCESS, variant: SUCCESS,
persist: false, persist: false,
autoHideDuration: shortDuration, autoHideDuration: shortDuration,
preventDuplicate: true, },
},
WALLET_DISCONNECTED_MSG: {
description: 'Wallet disconnected',
options: {
variant: SUCCESS,
persist: false,
autoHideDuration: shortDuration,
}, },
}, },
UNLOCK_WALLET_MSG: { UNLOCK_WALLET_MSG: {
description: 'Unlock your wallet to connect', description: 'Unlock your wallet to connect',
options: { variant: WARNING, persist: true }, options: { variant: WARNING, persist: true, preventDuplicate: true },
}, },
CONNECT_WALLET_ERROR_MSG: { CONNECT_WALLET_ERROR_MSG: {
description: 'Error connecting to your wallet', description: 'Error connecting to your wallet',
@ -200,14 +209,14 @@ export const NOTIFICATIONS: Notifications = {
// Network // Network
RINKEBY_VERSION_MSG: { RINKEBY_VERSION_MSG: {
description: "Rinkeby Version: Don't send mainnet assets to this Safe", description: "Rinkeby Version: Don't send mainnet assets to this Safe",
options: { variant: INFO, persist: true, hideIconVariant: true }, options: { variant: INFO, persist: true, preventDuplicate: true },
}, },
WRONG_NETWORK_RINKEBY_MSG: { WRONG_NETWORK_RINKEBY_MSG: {
description: 'Wrong network: Please use Rinkeby', description: 'Wrong network: Please use Rinkeby',
options: { variant: WARNING, persist: true }, options: { variant: WARNING, persist: true, preventDuplicate: true },
}, },
WRONG_NETWOEK_MAINNET_MSG: { WRONG_NETWOEK_MAINNET_MSG: {
description: 'Wrong network: Please use Mainnet', description: 'Wrong network: Please use Mainnet',
options: { variant: WARNING, persist: true }, options: { variant: WARNING, persist: true, preventDuplicate: true },
}, },
} }

View File

@ -4,6 +4,7 @@ export type NotifiedTransaction = {
CONNECT_WALLET_TX: string, CONNECT_WALLET_TX: string,
STANDARD_TX: string, STANDARD_TX: string,
CONFIRMATION_TX: string, CONFIRMATION_TX: string,
CANCELLATION_TX: string,
OWNER_CHANGE_TX: string, OWNER_CHANGE_TX: string,
SAFE_NAME_CHANGE_TX: string, SAFE_NAME_CHANGE_TX: string,
OWNER_NAME_CHANGE_TX: string, OWNER_NAME_CHANGE_TX: string,
@ -15,6 +16,7 @@ export const NOTIFIED_TRANSACTIONS: NotifiedTransaction = {
CONNECT_WALLET_TX: 'CONNECT_WALLET_TX', CONNECT_WALLET_TX: 'CONNECT_WALLET_TX',
STANDARD_TX: 'STANDARD_TX', STANDARD_TX: 'STANDARD_TX',
CONFIRMATION_TX: 'CONFIRMATION_TX', CONFIRMATION_TX: 'CONFIRMATION_TX',
CANCELLATION_TX: 'CANCELLATION_TX',
OWNER_CHANGE_TX: 'OWNER_CHANGE_TX', OWNER_CHANGE_TX: 'OWNER_CHANGE_TX',
SAFE_NAME_CHANGE_TX: 'SAFE_NAME_CHANGE_TX', SAFE_NAME_CHANGE_TX: 'SAFE_NAME_CHANGE_TX',
OWNER_NAME_CHANGE_TX: 'OWNER_NAME_CHANGE_TX', OWNER_NAME_CHANGE_TX: 'OWNER_NAME_CHANGE_TX',

View File

@ -121,6 +121,10 @@ export const getAddressFromENS = async (name: string) => {
} }
export const getBalanceInEtherOf = async (safeAddress: string) => { export const getBalanceInEtherOf = async (safeAddress: string) => {
if (!web3) {
return '0'
}
const funds: String = await web3.eth.getBalance(safeAddress) const funds: String = await web3.eth.getBalance(safeAddress)
if (!funds) { if (!funds) {

View File

@ -3,9 +3,7 @@ import type { Dispatch as ReduxDispatch } from 'redux'
import { ETHEREUM_NETWORK_IDS, ETHEREUM_NETWORK } from '~/logic/wallets/getWeb3' import { ETHEREUM_NETWORK_IDS, ETHEREUM_NETWORK } from '~/logic/wallets/getWeb3'
import type { ProviderProps } from '~/logic/wallets/store/model/provider' import type { ProviderProps } from '~/logic/wallets/store/model/provider'
import { makeProvider } from '~/logic/wallets/store/model/provider' import { makeProvider } from '~/logic/wallets/store/model/provider'
import { import { NOTIFICATIONS } from '~/logic/notifications'
type Variant, SUCCESS, ERROR, WARNING,
} from '~/components/Header'
import addProvider from './addProvider' import addProvider from './addProvider'
export const processProviderResponse = (dispatch: ReduxDispatch<*>, provider: ProviderProps) => { export const processProviderResponse = (dispatch: ReduxDispatch<*>, provider: ProviderProps) => {
@ -24,38 +22,35 @@ export const processProviderResponse = (dispatch: ReduxDispatch<*>, provider: Pr
dispatch(addProvider(walletRecord)) dispatch(addProvider(walletRecord))
} }
const handleProviderNotification = (enqueueSnackbar: Function, closeSnackbar: Function, provider: ProviderProps) => {
const CONNECT_WALLET_MSG = 'Please connect wallet to continue'
const CONNECT_WALLET_READ_MODE_MSG = 'You are in read-only mode: Please connect wallet'
const UNLOCK_MSG = 'Unlock your wallet to connect'
const WRONG_NETWORK_RINKEBY_MSG = 'Wrong network: Please use Rinkeby'
const SUCCESS_MSG = 'Wallet connected'
export const WALLET_ERROR_MSG = 'Error connecting to your wallet'
const handleProviderNotification = (
enqueueSnackbar: (message: string, variant: Variant) => void,
provider: ProviderProps,
) => {
const { loaded, available, network } = provider const { loaded, available, network } = provider
if (!loaded) { if (!loaded) {
enqueueSnackbar(WALLET_ERROR_MSG, { variant: ERROR }) enqueueSnackbar(NOTIFICATIONS.CONNECT_WALLET_ERROR_MSG.description, NOTIFICATIONS.CONNECT_WALLET_ERROR_MSG.options)
return return
} }
if (ETHEREUM_NETWORK_IDS[network] !== ETHEREUM_NETWORK.RINKEBY) { if (ETHEREUM_NETWORK_IDS[network] !== ETHEREUM_NETWORK.RINKEBY) {
enqueueSnackbar(WRONG_NETWORK_RINKEBY_MSG, { variant: ERROR, persist: true }) enqueueSnackbar(
NOTIFICATIONS.WRONG_NETWORK_RINKEBY_MSG.description,
NOTIFICATIONS.WRONG_NETWORK_RINKEBY_MSG.options,
)
return return
} }
enqueueSnackbar(NOTIFICATIONS.RINKEBY_VERSION_MSG.description, NOTIFICATIONS.RINKEBY_VERSION_MSG.options)
const msg = available ? SUCCESS_MSG : UNLOCK_MSG if (available) {
const variant = { variant: (available ? SUCCESS : WARNING) } enqueueSnackbar(NOTIFICATIONS.WALLET_CONNECTED_MSG.description, NOTIFICATIONS.WALLET_CONNECTED_MSG.options)
enqueueSnackbar(msg, variant) } else {
enqueueSnackbar(NOTIFICATIONS.UNLOCK_WALLET_MSG.description, NOTIFICATIONS.UNLOCK_WALLET_MSG.options)
}
} }
export default (provider: ProviderProps, enqueueSnackbar: (message: string, variant: Variant) => void) => ( export default (
dispatch: ReduxDispatch<*>, provider: ProviderProps,
) => { enqueueSnackbar: Function,
handleProviderNotification(enqueueSnackbar, provider) closeSnackbar: Function,
) => (dispatch: ReduxDispatch<*>) => {
handleProviderNotification(enqueueSnackbar, closeSnackbar, provider)
processProviderResponse(dispatch, provider) processProviderResponse(dispatch, provider)
} }

View File

@ -1,10 +1,10 @@
// @flow // @flow
import type { Dispatch as ReduxDispatch } from 'redux' import type { Dispatch as ReduxDispatch } from 'redux'
import { makeProvider, type ProviderProps, type Provider } from '~/logic/wallets/store/model/provider' import { makeProvider, type ProviderProps, type Provider } from '~/logic/wallets/store/model/provider'
import { type Variant, INFO } from '~/components/Header' import { NOTIFICATIONS } from '~/logic/notifications'
import addProvider from './addProvider' import addProvider from './addProvider'
export default (enqueueSnackbar: (message: string, variant: Variant) => void) => async (dispatch: ReduxDispatch<*>) => { export default (enqueueSnackbar: Function) => async (dispatch: ReduxDispatch<*>) => {
const providerProps: ProviderProps = { const providerProps: ProviderProps = {
name: '', name: '',
available: false, available: false,
@ -14,7 +14,7 @@ export default (enqueueSnackbar: (message: string, variant: Variant) => void) =>
} }
const provider: Provider = makeProvider(providerProps) const provider: Provider = makeProvider(providerProps)
enqueueSnackbar('Wallet disconnected succesfully', { variant: INFO }) enqueueSnackbar(NOTIFICATIONS.WALLET_DISCONNECTED_MSG.description, NOTIFICATIONS.WALLET_DISCONNECTED_MSG.options)
dispatch(addProvider(provider)) dispatch(addProvider(provider))
} }

View File

@ -69,7 +69,7 @@ const ReviewCustomTx = ({
txData, txData,
NOTIFIED_TRANSACTIONS.STANDARD_TX, NOTIFIED_TRANSACTIONS.STANDARD_TX,
enqueueSnackbar, enqueueSnackbar,
closeSnackbar closeSnackbar,
) )
onClose() onClose()
} }