Merge branch 'development' of github.com:gnosis/safe-react into bug-web3connect-android-fix
This commit is contained in:
commit
0e77694f5e
10
package.json
10
package.json
|
@ -33,7 +33,7 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@gnosis.pm/safe-contracts": "^1.0.0",
|
"@gnosis.pm/safe-contracts": "^1.0.0",
|
||||||
"@gnosis.pm/util-contracts": "2.0.4",
|
"@gnosis.pm/util-contracts": "2.0.4",
|
||||||
"@material-ui/core": "4.6.0",
|
"@material-ui/core": "4.6.1",
|
||||||
"@material-ui/icons": "4.5.1",
|
"@material-ui/icons": "4.5.1",
|
||||||
"@portis/web3": "^2.0.0-beta.45",
|
"@portis/web3": "^2.0.0-beta.45",
|
||||||
"@testing-library/jest-dom": "4.2.3",
|
"@testing-library/jest-dom": "4.2.3",
|
||||||
|
@ -57,7 +57,7 @@
|
||||||
"react-dom": "16.11.0",
|
"react-dom": "16.11.0",
|
||||||
"react-final-form": "6.3.0",
|
"react-final-form": "6.3.0",
|
||||||
"react-final-form-listeners": "^1.0.2",
|
"react-final-form-listeners": "^1.0.2",
|
||||||
"react-hot-loader": "4.12.16",
|
"react-hot-loader": "4.12.17",
|
||||||
"react-qr-reader": "^2.2.1",
|
"react-qr-reader": "^2.2.1",
|
||||||
"react-redux": "7.1.3",
|
"react-redux": "7.1.3",
|
||||||
"react-router-dom": "5.1.2",
|
"react-router-dom": "5.1.2",
|
||||||
|
@ -116,7 +116,7 @@
|
||||||
"detect-port": "^1.3.0",
|
"detect-port": "^1.3.0",
|
||||||
"eslint": "5.16.0",
|
"eslint": "5.16.0",
|
||||||
"eslint-config-airbnb": "18.0.1",
|
"eslint-config-airbnb": "18.0.1",
|
||||||
"eslint-plugin-flowtype": "4.3.0",
|
"eslint-plugin-flowtype": "4.4.1",
|
||||||
"eslint-plugin-import": "2.18.2",
|
"eslint-plugin-import": "2.18.2",
|
||||||
"eslint-plugin-jest": "23.0.3",
|
"eslint-plugin-jest": "23.0.3",
|
||||||
"eslint-plugin-jsx-a11y": "6.2.3",
|
"eslint-plugin-jsx-a11y": "6.2.3",
|
||||||
|
@ -124,7 +124,7 @@
|
||||||
"ethereumjs-abi": "0.6.8",
|
"ethereumjs-abi": "0.6.8",
|
||||||
"extract-text-webpack-plugin": "^4.0.0-beta.0",
|
"extract-text-webpack-plugin": "^4.0.0-beta.0",
|
||||||
"file-loader": "4.2.0",
|
"file-loader": "4.2.0",
|
||||||
"flow-bin": "0.111.3",
|
"flow-bin": "0.112.0",
|
||||||
"fs-extra": "8.1.0",
|
"fs-extra": "8.1.0",
|
||||||
"html-loader": "^0.5.5",
|
"html-loader": "^0.5.5",
|
||||||
"html-webpack-plugin": "^3.2.0",
|
"html-webpack-plugin": "^3.2.0",
|
||||||
|
@ -141,7 +141,7 @@
|
||||||
"storybook-host": "5.1.0",
|
"storybook-host": "5.1.0",
|
||||||
"storybook-router": "^0.3.4",
|
"storybook-router": "^0.3.4",
|
||||||
"style-loader": "1.0.0",
|
"style-loader": "1.0.0",
|
||||||
"truffle": "5.0.44",
|
"truffle": "5.1.0",
|
||||||
"truffle-contract": "4.0.31",
|
"truffle-contract": "4.0.31",
|
||||||
"truffle-solidity-loader": "0.1.32",
|
"truffle-solidity-loader": "0.1.32",
|
||||||
"uglifyjs-webpack-plugin": "2.2.0",
|
"uglifyjs-webpack-plugin": "2.2.0",
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
// @flow
|
// @flow
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import { connect } from 'react-redux'
|
|
||||||
import Web3Connect from 'web3connect'
|
import Web3Connect from 'web3connect'
|
||||||
import Torus from '@toruslabs/torus-embed'
|
import Torus from '@toruslabs/torus-embed'
|
||||||
import WalletConnectProvider from '@walletconnect/web3-provider'
|
import WalletConnectProvider from '@walletconnect/web3-provider'
|
||||||
|
@ -54,15 +53,11 @@ web3Connect.on('connect', (provider: any) => {
|
||||||
})
|
})
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
registerProvider: Function,
|
|
||||||
enqueueSnackbar: Function,
|
enqueueSnackbar: Function,
|
||||||
closeSnackbar: Function,
|
closeSnackbar: Function,
|
||||||
}
|
}
|
||||||
|
|
||||||
const ConnectButton = ({
|
const ConnectButton = (props: Props) => (
|
||||||
registerProvider, ...props
|
|
||||||
}: Props) => (
|
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
color="primary"
|
color="primary"
|
||||||
variant="contained"
|
variant="contained"
|
||||||
|
@ -76,7 +71,4 @@ const ConnectButton = ({
|
||||||
</Button>
|
</Button>
|
||||||
)
|
)
|
||||||
|
|
||||||
export default connect(
|
export default ConnectButton
|
||||||
null,
|
|
||||||
{ registerProvider: fetchProvider },
|
|
||||||
)(ConnectButton)
|
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
// @flow
|
||||||
|
import React from 'react'
|
||||||
|
import { makeStyles } from '@material-ui/core/styles'
|
||||||
|
import ReactDOM from 'react-dom'
|
||||||
|
import Backdrop from '@material-ui/core/Backdrop'
|
||||||
|
|
||||||
|
const useStyles = makeStyles({
|
||||||
|
root: {
|
||||||
|
zIndex: 1300,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const BackdropLayout = ({ isOpen = false }: { isOpen: boolean }) => {
|
||||||
|
if (!isOpen) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
const classes = useStyles()
|
||||||
|
|
||||||
|
return ReactDOM.createPortal(<Backdrop classes={{ root: classes.root }} open />, document.body)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default BackdropLayout
|
|
@ -0,0 +1,7 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20">
|
||||||
|
<g fill="none" fill-rule="evenodd">
|
||||||
|
<rect width="2" height="8" x="9" y="8" fill="#B2B5B2" rx="1"/>
|
||||||
|
<rect width="2" height="2" x="9" y="4" fill="#B2B5B2" stroke="#B2B5B2" stroke-width=".5" rx="1"/>
|
||||||
|
<circle cx="10" cy="10" r="9" stroke="#B2B5B2" stroke-width="2"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 391 B |
|
@ -1,14 +1,20 @@
|
||||||
// @flow
|
// @flow
|
||||||
import * as React from 'react'
|
import * as React from 'react'
|
||||||
|
import { connect } from 'react-redux'
|
||||||
import { SnackbarProvider } from 'notistack'
|
import { SnackbarProvider } from 'notistack'
|
||||||
import { withStyles } from '@material-ui/core/styles'
|
import { withStyles } from '@material-ui/core/styles'
|
||||||
|
import { getNetwork } from '~/config'
|
||||||
|
import { ETHEREUM_NETWORK } from '~/logic/wallets/getWeb3'
|
||||||
import SidebarProvider from '~/components/Sidebar'
|
import SidebarProvider from '~/components/Sidebar'
|
||||||
import Header from '~/components/Header'
|
import Header from '~/components/Header'
|
||||||
|
import Backdrop from '~/components/layout/Backdrop'
|
||||||
import Img from '~/components/layout/Img'
|
import Img from '~/components/layout/Img'
|
||||||
import Notifier from '~/components/Notifier'
|
import Notifier from '~/components/Notifier'
|
||||||
import AlertLogo from './assets/alert.svg'
|
import { networkSelector } from '~/logic/wallets/store/selectors'
|
||||||
import CheckLogo from './assets/check.svg'
|
import AlertIcon from './assets/alert.svg'
|
||||||
import ErrorLogo from './assets/error.svg'
|
import CheckIcon from './assets/check.svg'
|
||||||
|
import ErrorIcon from './assets/error.svg'
|
||||||
|
import InfoIcon from './assets/info.svg'
|
||||||
import styles from './index.scss'
|
import styles from './index.scss'
|
||||||
|
|
||||||
const notificationStyles = {
|
const notificationStyles = {
|
||||||
|
@ -40,11 +46,11 @@ const notificationStyles = {
|
||||||
boxShadow: '0 0 10px 0 rgba(212, 212, 211, 0.59)',
|
boxShadow: '0 0 10px 0 rgba(212, 212, 211, 0.59)',
|
||||||
},
|
},
|
||||||
info: {
|
info: {
|
||||||
background: '#e8673c',
|
background: '#ffffff',
|
||||||
fontFamily: 'Averta',
|
fontFamily: 'Averta',
|
||||||
fontSize: '14px',
|
fontSize: '14px',
|
||||||
lineHeight: 1.43,
|
lineHeight: 1.43,
|
||||||
color: '#ffffff',
|
color: '#001428',
|
||||||
minHeight: '58px',
|
minHeight: '58px',
|
||||||
boxShadow: '0 0 10px 0 rgba(212, 212, 211, 0.59)',
|
boxShadow: '0 0 10px 0 rgba(212, 212, 211, 0.59)',
|
||||||
},
|
},
|
||||||
|
@ -53,33 +59,48 @@ const notificationStyles = {
|
||||||
type Props = {
|
type Props = {
|
||||||
children: React.Node,
|
children: React.Node,
|
||||||
classes: Object,
|
classes: Object,
|
||||||
|
currentNetwork: string,
|
||||||
}
|
}
|
||||||
|
|
||||||
const PageFrame = ({ children, classes }: Props) => (
|
const desiredNetwork = getNetwork()
|
||||||
<div className={styles.frame}>
|
|
||||||
<SnackbarProvider
|
|
||||||
maxSnack={5}
|
|
||||||
anchorOrigin={{ vertical: 'top', horizontal: 'right' }}
|
|
||||||
classes={{
|
|
||||||
variantSuccess: classes.success,
|
|
||||||
variantError: classes.error,
|
|
||||||
variantWarning: classes.warning,
|
|
||||||
variantInfo: classes.info,
|
|
||||||
}}
|
|
||||||
iconVariant={{
|
|
||||||
success: <Img src={CheckLogo} alt="Success" />,
|
|
||||||
error: <Img src={ErrorLogo} alt="Error" />,
|
|
||||||
warning: <Img src={AlertLogo} alt="Warning" />,
|
|
||||||
info: '',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Notifier />
|
|
||||||
<SidebarProvider>
|
|
||||||
<Header />
|
|
||||||
{children}
|
|
||||||
</SidebarProvider>
|
|
||||||
</SnackbarProvider>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
|
|
||||||
export default withStyles(notificationStyles)(PageFrame)
|
const PageFrame = ({ children, classes, currentNetwork }: Props) => {
|
||||||
|
const isWrongNetwork = currentNetwork !== ETHEREUM_NETWORK.UNKNOWN && currentNetwork !== desiredNetwork
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={styles.frame}>
|
||||||
|
<Backdrop isOpen={isWrongNetwork} />
|
||||||
|
<SnackbarProvider
|
||||||
|
maxSnack={5}
|
||||||
|
anchorOrigin={{ vertical: 'top', horizontal: 'right' }}
|
||||||
|
classes={{
|
||||||
|
variantSuccess: classes.success,
|
||||||
|
variantError: classes.error,
|
||||||
|
variantWarning: classes.warning,
|
||||||
|
variantInfo: classes.info,
|
||||||
|
}}
|
||||||
|
iconVariant={{
|
||||||
|
success: <Img src={CheckIcon} alt="Success" />,
|
||||||
|
error: <Img src={ErrorIcon} alt="Error" />,
|
||||||
|
warning: <Img src={AlertIcon} alt="Warning" />,
|
||||||
|
info: <Img src={InfoIcon} alt="Info" />,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Notifier />
|
||||||
|
<SidebarProvider>
|
||||||
|
<Header />
|
||||||
|
{children}
|
||||||
|
</SidebarProvider>
|
||||||
|
</SnackbarProvider>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default withStyles(notificationStyles)(
|
||||||
|
connect(
|
||||||
|
(state) => ({
|
||||||
|
currentNetwork: networkSelector(state),
|
||||||
|
}),
|
||||||
|
null,
|
||||||
|
)(PageFrame),
|
||||||
|
)
|
||||||
|
|
|
@ -8,101 +8,90 @@ import closeSnackbarAction from '~/logic/notifications/store/actions/closeSnackb
|
||||||
import { type Notification, NOTIFICATIONS } from './notificationTypes'
|
import { type Notification, NOTIFICATIONS } from './notificationTypes'
|
||||||
|
|
||||||
export type NotificationsQueue = {
|
export type NotificationsQueue = {
|
||||||
beforeExecution: Notification,
|
beforeExecution: Notification | null,
|
||||||
pendingExecution: {
|
pendingExecution: Notification | null,
|
||||||
noMoreConfirmationsNeeded: Notification,
|
afterExecution: {
|
||||||
moreConfirmationsNeeded: Notification,
|
noMoreConfirmationsNeeded: Notification | null,
|
||||||
|
moreConfirmationsNeeded: Notification | null,
|
||||||
},
|
},
|
||||||
afterExecution: Notification,
|
afterExecutionError: Notification | null,
|
||||||
afterExecutionError: Notification,
|
afterRejection: Notification | null,
|
||||||
afterRejection: Notification,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const standardTxNotificationsQueue: NotificationsQueue = {
|
const standardTxNotificationsQueue: NotificationsQueue = {
|
||||||
beforeExecution: NOTIFICATIONS.SIGN_TX_MSG,
|
beforeExecution: NOTIFICATIONS.SIGN_TX_MSG,
|
||||||
pendingExecution: {
|
pendingExecution: NOTIFICATIONS.TX_PENDING_MSG,
|
||||||
noMoreConfirmationsNeeded: NOTIFICATIONS.TX_PENDING_MSG,
|
|
||||||
moreConfirmationsNeeded: NOTIFICATIONS.TX_PENDING_MORE_CONFIRMATIONS_MSG,
|
|
||||||
},
|
|
||||||
afterRejection: NOTIFICATIONS.TX_REJECTED_MSG,
|
afterRejection: NOTIFICATIONS.TX_REJECTED_MSG,
|
||||||
afterExecution: NOTIFICATIONS.TX_EXECUTED_MSG,
|
afterExecution: {
|
||||||
|
noMoreConfirmationsNeeded: NOTIFICATIONS.TX_EXECUTED_MSG,
|
||||||
|
moreConfirmationsNeeded: NOTIFICATIONS.TX_EXECUTED_MORE_CONFIRMATIONS_MSG,
|
||||||
|
},
|
||||||
afterExecutionError: NOTIFICATIONS.TX_FAILED_MSG,
|
afterExecutionError: NOTIFICATIONS.TX_FAILED_MSG,
|
||||||
}
|
}
|
||||||
|
|
||||||
const confirmationTxNotificationsQueue: NotificationsQueue = {
|
const confirmationTxNotificationsQueue: NotificationsQueue = {
|
||||||
beforeExecution: NOTIFICATIONS.SIGN_TX_MSG,
|
beforeExecution: NOTIFICATIONS.SIGN_TX_MSG,
|
||||||
pendingExecution: {
|
pendingExecution: NOTIFICATIONS.TX_CONFIRMATION_PENDING_MSG,
|
||||||
noMoreConfirmationsNeeded: NOTIFICATIONS.TX_CONFIRMATION_PENDING_MSG,
|
afterRejection: NOTIFICATIONS.TX_REJECTED_MSG,
|
||||||
|
afterExecution: {
|
||||||
|
noMoreConfirmationsNeeded: NOTIFICATIONS.TX_CONFIRMATION_EXECUTED_MSG,
|
||||||
moreConfirmationsNeeded: null,
|
moreConfirmationsNeeded: null,
|
||||||
},
|
},
|
||||||
afterRejection: NOTIFICATIONS.TX_REJECTED_MSG,
|
|
||||||
afterExecution: NOTIFICATIONS.TX_CONFIRMATION_EXECUTED_MSG,
|
|
||||||
afterExecutionError: NOTIFICATIONS.TX_CONFIRMATION_FAILED_MSG,
|
afterExecutionError: NOTIFICATIONS.TX_CONFIRMATION_FAILED_MSG,
|
||||||
}
|
}
|
||||||
|
|
||||||
const cancellationTxNotificationsQueue: NotificationsQueue = {
|
const cancellationTxNotificationsQueue: NotificationsQueue = {
|
||||||
beforeExecution: NOTIFICATIONS.SIGN_TX_MSG,
|
beforeExecution: NOTIFICATIONS.SIGN_TX_MSG,
|
||||||
pendingExecution: {
|
pendingExecution: NOTIFICATIONS.TX_PENDING_MSG,
|
||||||
noMoreConfirmationsNeeded: NOTIFICATIONS.TX_PENDING_MSG,
|
|
||||||
moreConfirmationsNeeded: NOTIFICATIONS.TX_PENDING_MORE_CONFIRMATIONS_MSG,
|
|
||||||
},
|
|
||||||
afterRejection: NOTIFICATIONS.TX_REJECTED_MSG,
|
afterRejection: NOTIFICATIONS.TX_REJECTED_MSG,
|
||||||
afterExecution: NOTIFICATIONS.TX_EXECUTED_MSG,
|
afterExecution: {
|
||||||
afterExecutionError: NOTIFICATIONS.TX_FAILED_MSG,
|
noMoreConfirmationsNeeded: NOTIFICATIONS.TX_EXECUTED_MSG,
|
||||||
}
|
moreConfirmationsNeeded: NOTIFICATIONS.TX_EXECUTED_MORE_CONFIRMATIONS_MSG,
|
||||||
|
|
||||||
const ownerChangeTxNotificationsQueue: NotificationsQueue = {
|
|
||||||
beforeExecution: NOTIFICATIONS.SIGN_OWNER_CHANGE_MSG,
|
|
||||||
pendingExecution: {
|
|
||||||
noMoreConfirmationsNeeded: NOTIFICATIONS.OWNER_CHANGE_PENDING_MSG,
|
|
||||||
moreConfirmationsNeeded: NOTIFICATIONS.OWNER_CHANGE_PENDING_MORE_CONFIRMATIONS_MSG,
|
|
||||||
},
|
},
|
||||||
afterRejection: NOTIFICATIONS.OWNER_CHANGE_REJECTED_MSG,
|
afterExecutionError: NOTIFICATIONS.TX_FAILED_MSG,
|
||||||
afterExecution: NOTIFICATIONS.OWNER_CHANGE_EXECUTED_MSG,
|
|
||||||
afterExecutionError: NOTIFICATIONS.OWNER_CHANGE_FAILED_MSG,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const safeNameChangeNotificationsQueue: NotificationsQueue = {
|
const safeNameChangeNotificationsQueue: NotificationsQueue = {
|
||||||
beforeExecution: null,
|
beforeExecution: null,
|
||||||
pendingExecution: {
|
pendingExecution: null,
|
||||||
noMoreConfirmationsNeeded: null,
|
afterRejection: null,
|
||||||
|
afterExecution: {
|
||||||
|
noMoreConfirmationsNeeded: NOTIFICATIONS.SAFE_NAME_CHANGED_MSG,
|
||||||
moreConfirmationsNeeded: null,
|
moreConfirmationsNeeded: null,
|
||||||
},
|
},
|
||||||
afterRejection: null,
|
|
||||||
afterExecution: NOTIFICATIONS.SAFE_NAME_CHANGED_MSG,
|
|
||||||
afterExecutionError: null,
|
afterExecutionError: null,
|
||||||
}
|
}
|
||||||
|
|
||||||
const ownerNameChangeNotificationsQueue: NotificationsQueue = {
|
const ownerNameChangeNotificationsQueue: NotificationsQueue = {
|
||||||
beforeExecution: null,
|
beforeExecution: null,
|
||||||
pendingExecution: {
|
pendingExecution: null,
|
||||||
noMoreConfirmationsNeeded: null,
|
afterRejection: null,
|
||||||
|
afterExecution: {
|
||||||
|
noMoreConfirmationsNeeded: NOTIFICATIONS.OWNER_NAME_CHANGE_EXECUTED_MSG,
|
||||||
moreConfirmationsNeeded: null,
|
moreConfirmationsNeeded: null,
|
||||||
},
|
},
|
||||||
afterRejection: null,
|
|
||||||
afterExecution: NOTIFICATIONS.OWNER_NAME_CHANGE_EXECUTED_MSG,
|
|
||||||
afterExecutionError: null,
|
afterExecutionError: null,
|
||||||
}
|
}
|
||||||
|
|
||||||
const thresholdChangeTxNotificationsQueue: NotificationsQueue = {
|
const settingsChangeTxNotificationsQueue: NotificationsQueue = {
|
||||||
beforeExecution: NOTIFICATIONS.SIGN_THRESHOLD_CHANGE_MSG,
|
beforeExecution: NOTIFICATIONS.SIGN_SETTINGS_CHANGE_MSG,
|
||||||
pendingExecution: {
|
pendingExecution: NOTIFICATIONS.SETTINGS_CHANGE_PENDING_MSG,
|
||||||
noMoreConfirmationsNeeded: NOTIFICATIONS.THRESHOLD_CHANGE_PENDING_MSG,
|
afterRejection: NOTIFICATIONS.SETTINGS_CHANGE_REJECTED_MSG,
|
||||||
moreConfirmationsNeeded: NOTIFICATIONS.THRESHOLD_CHANGE_PENDING_MORE_CONFIRMATIONS_MSG,
|
afterExecution: {
|
||||||
|
noMoreConfirmationsNeeded: NOTIFICATIONS.SETTINGS_CHANGE_EXECUTED_MSG,
|
||||||
|
moreConfirmationsNeeded: NOTIFICATIONS.SETTINGS_CHANGE_EXECUTED_MORE_CONFIRMATIONS_MSG,
|
||||||
},
|
},
|
||||||
afterRejection: NOTIFICATIONS.THRESHOLD_CHANGE_REJECTED_MSG,
|
afterExecutionError: NOTIFICATIONS.SETTINGS_CHANGE_FAILED_MSG,
|
||||||
afterExecution: NOTIFICATIONS.THRESHOLD_CHANGE_EXECUTED_MSG,
|
|
||||||
afterExecutionError: NOTIFICATIONS.THRESHOLD_CHANGE_FAILED_MSG,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const defaultNotificationsQueue: NotificationsQueue = {
|
const defaultNotificationsQueue: NotificationsQueue = {
|
||||||
beforeExecution: NOTIFICATIONS.SIGN_TX_MSG,
|
beforeExecution: NOTIFICATIONS.SIGN_TX_MSG,
|
||||||
pendingExecution: {
|
pendingExecution: NOTIFICATIONS.TX_PENDING_MSG,
|
||||||
noMoreConfirmationsNeeded: NOTIFICATIONS.TX_PENDING_MSG,
|
|
||||||
moreConfirmationsNeeded: NOTIFICATIONS.TX_PENDING_MORE_CONFIRMATIONS_MSG,
|
|
||||||
},
|
|
||||||
afterRejection: NOTIFICATIONS.TX_REJECTED_MSG,
|
afterRejection: NOTIFICATIONS.TX_REJECTED_MSG,
|
||||||
afterExecution: NOTIFICATIONS.TX_EXECUTED_MSG,
|
afterExecution: {
|
||||||
|
noMoreConfirmationsNeeded: NOTIFICATIONS.TX_EXECUTED_MSG,
|
||||||
|
moreConfirmationsNeeded: NOTIFICATIONS.TX_EXECUTED_MORE_CONFIRMATIONS_MSG,
|
||||||
|
},
|
||||||
afterExecutionError: NOTIFICATIONS.TX_FAILED_MSG,
|
afterExecutionError: NOTIFICATIONS.TX_FAILED_MSG,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,8 +111,8 @@ export const getNotificationsFromTxType = (txType: string) => {
|
||||||
notificationsQueue = cancellationTxNotificationsQueue
|
notificationsQueue = cancellationTxNotificationsQueue
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
case TX_NOTIFICATION_TYPES.OWNER_CHANGE_TX: {
|
case TX_NOTIFICATION_TYPES.SETTINGS_CHANGE_TX: {
|
||||||
notificationsQueue = ownerChangeTxNotificationsQueue
|
notificationsQueue = settingsChangeTxNotificationsQueue
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
case TX_NOTIFICATION_TYPES.SAFE_NAME_CHANGE_TX: {
|
case TX_NOTIFICATION_TYPES.SAFE_NAME_CHANGE_TX: {
|
||||||
|
@ -134,10 +123,6 @@ export const getNotificationsFromTxType = (txType: string) => {
|
||||||
notificationsQueue = ownerNameChangeNotificationsQueue
|
notificationsQueue = ownerNameChangeNotificationsQueue
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
case TX_NOTIFICATION_TYPES.THRESHOLD_CHANGE_TX: {
|
|
||||||
notificationsQueue = thresholdChangeTxNotificationsQueue
|
|
||||||
break
|
|
||||||
}
|
|
||||||
default: {
|
default: {
|
||||||
notificationsQueue = defaultNotificationsQueue
|
notificationsQueue = defaultNotificationsQueue
|
||||||
break
|
break
|
||||||
|
@ -151,8 +136,8 @@ export const enhanceSnackbarForAction = (notification: Notification) => ({
|
||||||
...notification,
|
...notification,
|
||||||
options: {
|
options: {
|
||||||
...notification.options,
|
...notification.options,
|
||||||
action: (key) => (
|
action: (key: number) => (
|
||||||
<IconButton onClick={() => store.dispatch(closeSnackbarAction(key))}>
|
<IconButton onClick={() => store.dispatch(closeSnackbarAction({ key }))}>
|
||||||
<IconClose />
|
<IconClose />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
),
|
),
|
||||||
|
|
|
@ -34,9 +34,9 @@ export type Notifications = {
|
||||||
// Regular/Custom Transactions
|
// Regular/Custom Transactions
|
||||||
SIGN_TX_MSG: Notification,
|
SIGN_TX_MSG: Notification,
|
||||||
TX_PENDING_MSG: Notification,
|
TX_PENDING_MSG: Notification,
|
||||||
TX_PENDING_MORE_CONFIRMATIONS_MSG: Notification,
|
|
||||||
TX_REJECTED_MSG: Notification,
|
TX_REJECTED_MSG: Notification,
|
||||||
TX_EXECUTED_MSG: Notification,
|
TX_EXECUTED_MSG: Notification,
|
||||||
|
TX_EXECUTED_MORE_CONFIRMATIONS_MSG: Notification,
|
||||||
TX_FAILED_MSG: Notification,
|
TX_FAILED_MSG: Notification,
|
||||||
|
|
||||||
// Approval Transactions
|
// Approval Transactions
|
||||||
|
@ -51,20 +51,11 @@ export type Notifications = {
|
||||||
OWNER_NAME_CHANGE_EXECUTED_MSG: Notification,
|
OWNER_NAME_CHANGE_EXECUTED_MSG: Notification,
|
||||||
|
|
||||||
// Owners
|
// Owners
|
||||||
SIGN_OWNER_CHANGE_MSG: Notification,
|
SIGN_SETTINGS_CHANGE_MSG: Notification,
|
||||||
OWNER_CHANGE_PENDING_MSG: Notification,
|
SETTINGS_CHANGE_PENDING_MSG: Notification,
|
||||||
OWNER_CHANGE_PENDING_MORE_CONFIRMATIONS_MSG: Notification,
|
SETTINGS_CHANGE_REJECTED_MSG: Notification,
|
||||||
OWNER_CHANGE_REJECTED_MSG: Notification,
|
SETTINGS_CHANGE_EXECUTED_MORE_CONFIRMATIONS_MSG: Notification,
|
||||||
OWNER_CHANGE_EXECUTED_MSG: Notification,
|
SETTINGS_CHANGE_FAILED_MSG: Notification,
|
||||||
OWNER_CHANGE_FAILED_MSG: Notification,
|
|
||||||
|
|
||||||
// Threshold
|
|
||||||
SIGN_THRESHOLD_CHANGE_MSG: Notification,
|
|
||||||
THRESHOLD_CHANGE_PENDING_MSG: Notification,
|
|
||||||
THRESHOLD_CHANGE_PENDING_MORE_CONFIRMATIONS_MSG: Notification,
|
|
||||||
THRESHOLD_CHANGE_REJECTED_MSG: Notification,
|
|
||||||
THRESHOLD_CHANGE_EXECUTED_MSG: Notification,
|
|
||||||
THRESHOLD_CHANGE_FAILED_MSG: Notification,
|
|
||||||
|
|
||||||
// Rinkeby version
|
// Rinkeby version
|
||||||
RINKEBY_VERSION_MSG: Notification,
|
RINKEBY_VERSION_MSG: Notification,
|
||||||
|
@ -109,15 +100,11 @@ export const NOTIFICATIONS: Notifications = {
|
||||||
// Regular/Custom Transactions
|
// Regular/Custom Transactions
|
||||||
SIGN_TX_MSG: {
|
SIGN_TX_MSG: {
|
||||||
message: 'Please sign the transaction',
|
message: 'Please sign the transaction',
|
||||||
options: { variant: SUCCESS, persist: true },
|
options: { variant: INFO, persist: true },
|
||||||
},
|
},
|
||||||
TX_PENDING_MSG: {
|
TX_PENDING_MSG: {
|
||||||
message: 'Transaction pending',
|
message: 'Transaction pending',
|
||||||
options: { variant: SUCCESS, persist: true },
|
options: { variant: INFO, persist: true },
|
||||||
},
|
|
||||||
TX_PENDING_MORE_CONFIRMATIONS_MSG: {
|
|
||||||
message: 'Transaction pending: More confirmations required to execute',
|
|
||||||
options: { variant: SUCCESS, persist: true },
|
|
||||||
},
|
},
|
||||||
TX_REJECTED_MSG: {
|
TX_REJECTED_MSG: {
|
||||||
message: 'Transaction rejected',
|
message: 'Transaction rejected',
|
||||||
|
@ -127,6 +114,10 @@ export const NOTIFICATIONS: Notifications = {
|
||||||
message: 'Transaction successfully executed',
|
message: 'Transaction successfully executed',
|
||||||
options: { variant: SUCCESS, persist: false, autoHideDuration: longDuration },
|
options: { variant: SUCCESS, persist: false, autoHideDuration: longDuration },
|
||||||
},
|
},
|
||||||
|
TX_EXECUTED_MORE_CONFIRMATIONS_MSG: {
|
||||||
|
message: 'Transaction successfully created. More confirmations needed to execute',
|
||||||
|
options: { variant: SUCCESS, persist: false, autoHideDuration: longDuration },
|
||||||
|
},
|
||||||
TX_FAILED_MSG: {
|
TX_FAILED_MSG: {
|
||||||
message: 'Transaction failed',
|
message: 'Transaction failed',
|
||||||
options: { variant: ERROR, persist: false, autoHideDuration: longDuration },
|
options: { variant: ERROR, persist: false, autoHideDuration: longDuration },
|
||||||
|
@ -135,7 +126,7 @@ export const NOTIFICATIONS: Notifications = {
|
||||||
// Approval Transactions
|
// Approval Transactions
|
||||||
TX_CONFIRMATION_PENDING_MSG: {
|
TX_CONFIRMATION_PENDING_MSG: {
|
||||||
message: 'Confirmation transaction pending',
|
message: 'Confirmation transaction pending',
|
||||||
options: { variant: SUCCESS, persist: true },
|
options: { variant: INFO, persist: true },
|
||||||
},
|
},
|
||||||
TX_CONFIRMATION_EXECUTED_MSG: {
|
TX_CONFIRMATION_EXECUTED_MSG: {
|
||||||
message: 'Confirmation transaction succesful',
|
message: 'Confirmation transaction succesful',
|
||||||
|
@ -158,62 +149,36 @@ export const NOTIFICATIONS: Notifications = {
|
||||||
options: { variant: SUCCESS, persist: false, autoHideDuration: shortDuration },
|
options: { variant: SUCCESS, persist: false, autoHideDuration: shortDuration },
|
||||||
},
|
},
|
||||||
|
|
||||||
// Owners
|
// Settings
|
||||||
SIGN_OWNER_CHANGE_MSG: {
|
SIGN_SETTINGS_CHANGE_MSG: {
|
||||||
message: 'Please sign the owner change',
|
message: 'Please sign the settings change',
|
||||||
options: { variant: SUCCESS, persist: true },
|
options: { variant: INFO, persist: true },
|
||||||
},
|
},
|
||||||
OWNER_CHANGE_PENDING_MSG: {
|
SETTINGS_CHANGE_PENDING_MSG: {
|
||||||
message: 'Owner change pending',
|
message: 'Settings change pending',
|
||||||
options: { variant: SUCCESS, persist: true },
|
options: { variant: INFO, persist: true },
|
||||||
},
|
},
|
||||||
OWNER_CHANGE_PENDING_MORE_CONFIRMATIONS_MSG: {
|
SETTINGS_CHANGE_REJECTED_MSG: {
|
||||||
message: 'Owner change pending: More confirmations required to execute',
|
message: 'Settings change rejected',
|
||||||
options: { variant: SUCCESS, persist: true },
|
|
||||||
},
|
|
||||||
OWNER_CHANGE_REJECTED_MSG: {
|
|
||||||
message: 'Owner change rejected',
|
|
||||||
options: { variant: ERROR, persist: false, autoHideDuration: longDuration },
|
options: { variant: ERROR, persist: false, autoHideDuration: longDuration },
|
||||||
},
|
},
|
||||||
OWNER_CHANGE_EXECUTED_MSG: {
|
SETTINGS_CHANGE_EXECUTED_MSG: {
|
||||||
message: 'Owner change successfully executed',
|
message: 'Settings change successfully executed',
|
||||||
options: { variant: SUCCESS, persist: false, autoHideDuration: longDuration },
|
options: { variant: SUCCESS, persist: false, autoHideDuration: longDuration },
|
||||||
},
|
},
|
||||||
OWNER_CHANGE_FAILED_MSG: {
|
SETTINGS_CHANGE_EXECUTED_MORE_CONFIRMATIONS_MSG: {
|
||||||
message: 'Owner change failed',
|
message: 'Settings change successfully created. More confirmations needed to execute',
|
||||||
options: { variant: ERROR, persist: false, autoHideDuration: longDuration },
|
|
||||||
},
|
|
||||||
|
|
||||||
// Threshold
|
|
||||||
SIGN_THRESHOLD_CHANGE_MSG: {
|
|
||||||
message: 'Please sign the required confirmations change',
|
|
||||||
options: { variant: SUCCESS, persist: true },
|
|
||||||
},
|
|
||||||
THRESHOLD_CHANGE_PENDING_MSG: {
|
|
||||||
message: 'Required confirmations change pending',
|
|
||||||
options: { variant: SUCCESS, persist: true },
|
|
||||||
},
|
|
||||||
THRESHOLD_CHANGE_PENDING_MORE_CONFIRMATIONS_MSG: {
|
|
||||||
message: 'Required confirmations change pending: More confirmations required to execute',
|
|
||||||
options: { variant: SUCCESS, persist: true },
|
|
||||||
},
|
|
||||||
THRESHOLD_CHANGE_REJECTED_MSG: {
|
|
||||||
message: 'Required confirmations change rejected',
|
|
||||||
options: { variant: ERROR, persist: false, autoHideDuration: longDuration },
|
|
||||||
},
|
|
||||||
THRESHOLD_CHANGE_EXECUTED_MSG: {
|
|
||||||
message: 'Required confirmations change successfully executed',
|
|
||||||
options: { variant: SUCCESS, persist: false, autoHideDuration: longDuration },
|
options: { variant: SUCCESS, persist: false, autoHideDuration: longDuration },
|
||||||
},
|
},
|
||||||
THRESHOLD_CHANGE_FAILED_MSG: {
|
SETTINGS_CHANGE_FAILED_MSG: {
|
||||||
message: 'Required confirmations change failed',
|
message: 'Settings change failed',
|
||||||
options: { variant: ERROR, persist: false, autoHideDuration: longDuration },
|
options: { variant: ERROR, persist: false, autoHideDuration: longDuration },
|
||||||
},
|
},
|
||||||
|
|
||||||
// Network
|
// Network
|
||||||
RINKEBY_VERSION_MSG: {
|
RINKEBY_VERSION_MSG: {
|
||||||
message: "Rinkeby Version: Don't send Mainnet assets to this Safe",
|
message: "Rinkeby Version: Don't send Mainnet assets to this Safe",
|
||||||
options: { variant: INFO, persist: true, preventDuplicate: true },
|
options: { variant: WARNING, persist: true, preventDuplicate: true },
|
||||||
},
|
},
|
||||||
WRONG_NETWORK_MSG: {
|
WRONG_NETWORK_MSG: {
|
||||||
message: `Wrong network: Please use ${capitalize(getNetwork())}`,
|
message: `Wrong network: Please use ${capitalize(getNetwork())}`,
|
||||||
|
|
|
@ -18,9 +18,20 @@ export default handleActions<NotificationReducerState, *>(
|
||||||
return state.set(notification.key, makeNotification(notification))
|
return state.set(notification.key, makeNotification(notification))
|
||||||
},
|
},
|
||||||
[CLOSE_SNACKBAR]: (state: NotificationReducerState, action: ActionType<Function>): NotificationReducerState => {
|
[CLOSE_SNACKBAR]: (state: NotificationReducerState, action: ActionType<Function>): NotificationReducerState => {
|
||||||
const key = action.payload
|
const { key, dismissAll } = action.payload
|
||||||
|
|
||||||
return state.update(key, (prev) => prev.set('dismissed', true))
|
if (key) {
|
||||||
|
return state.update(key, (prev) => prev.set('dismissed', true))
|
||||||
|
}
|
||||||
|
if (dismissAll) {
|
||||||
|
return state.withMutations((map) => {
|
||||||
|
map.forEach((notification, notificationKey) => {
|
||||||
|
map.set(notificationKey, notification.set('dismissed', true))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return state
|
||||||
},
|
},
|
||||||
[REMOVE_SNACKBAR]: (state: NotificationReducerState, action: ActionType<Function>): NotificationReducerState => {
|
[REMOVE_SNACKBAR]: (state: NotificationReducerState, action: ActionType<Function>): NotificationReducerState => {
|
||||||
const key = action.payload
|
const key = action.payload
|
||||||
|
|
|
@ -1,71 +0,0 @@
|
||||||
// @flow
|
|
||||||
import { List } from 'immutable'
|
|
||||||
import { type Transaction } from '~/routes/safe/store/models/transaction'
|
|
||||||
import { executeTransaction, approveTransaction } from '~/logic/safe/transactions'
|
|
||||||
import { EMPTY_DATA } from '~/logic/wallets/ethTransactions'
|
|
||||||
import { getWeb3 } from '~/logic/wallets/getWeb3'
|
|
||||||
import { type Safe } from '~/routes/safe/store/models/safe'
|
|
||||||
import { storeSubject } from '~/utils/storage/transactions'
|
|
||||||
|
|
||||||
export const TX_NAME_PARAM = 'txName'
|
|
||||||
export const TX_DESTINATION_PARAM = 'txDestination'
|
|
||||||
export const TX_VALUE_PARAM = 'txValue'
|
|
||||||
|
|
||||||
export const EXECUTED_CONFIRMATION_HASH = 'EXECUTED'
|
|
||||||
|
|
||||||
const hasOneOwner = (safe: Safe) => {
|
|
||||||
const owners = safe.get('owners')
|
|
||||||
if (!owners) {
|
|
||||||
throw new Error('Received a Safe without owners when creating a tx')
|
|
||||||
}
|
|
||||||
|
|
||||||
return owners.count() === 1
|
|
||||||
}
|
|
||||||
|
|
||||||
export const createTransaction = async (
|
|
||||||
safe: Safe,
|
|
||||||
name: string,
|
|
||||||
to: string,
|
|
||||||
value: string,
|
|
||||||
nonce: number,
|
|
||||||
sender: string,
|
|
||||||
data: string = EMPTY_DATA,
|
|
||||||
) => {
|
|
||||||
const web3 = getWeb3()
|
|
||||||
const safeAddress = safe.get('address')
|
|
||||||
const threshold = safe.get('threshold')
|
|
||||||
const valueInWei = web3.utils.toWei(value, 'ether')
|
|
||||||
const CALL = 0
|
|
||||||
|
|
||||||
const isExecution = hasOneOwner(safe) || threshold === 1
|
|
||||||
|
|
||||||
const txHash = isExecution
|
|
||||||
? await executeTransaction(safeAddress, to, valueInWei, data, CALL, nonce, sender, List([]))
|
|
||||||
: await approveTransaction(safeAddress, to, valueInWei, data, CALL, nonce, sender)
|
|
||||||
|
|
||||||
storeSubject(safeAddress, nonce, name)
|
|
||||||
|
|
||||||
return txHash
|
|
||||||
}
|
|
||||||
|
|
||||||
export const processTransaction = async (
|
|
||||||
safeAddress: string,
|
|
||||||
tx: Transaction,
|
|
||||||
alreadyConfirmed: number,
|
|
||||||
sender: string,
|
|
||||||
threshold: number,
|
|
||||||
usersConfirmed: List<string>,
|
|
||||||
) => {
|
|
||||||
const nonce = tx.get('nonce')
|
|
||||||
const valueInWei = tx.get('value')
|
|
||||||
const to = tx.get('destination')
|
|
||||||
const data = tx.get('data')
|
|
||||||
const CALL = 0
|
|
||||||
|
|
||||||
const thresholdReached = threshold === alreadyConfirmed + 1
|
|
||||||
const txHash = thresholdReached
|
|
||||||
? await executeTransaction(safeAddress, to, valueInWei, data, CALL, nonce, sender, usersConfirmed)
|
|
||||||
: await approveTransaction(safeAddress, to, valueInWei, data, CALL, nonce, sender)
|
|
||||||
|
|
||||||
return txHash
|
|
||||||
}
|
|
|
@ -4,18 +4,16 @@ export type NotifiedTransaction = {
|
||||||
STANDARD_TX: string,
|
STANDARD_TX: string,
|
||||||
CONFIRMATION_TX: string,
|
CONFIRMATION_TX: string,
|
||||||
CANCELLATION_TX: string,
|
CANCELLATION_TX: string,
|
||||||
OWNER_CHANGE_TX: string,
|
SETTINGS_CHANGE_TX: string,
|
||||||
SAFE_NAME_CHANGE_TX: string,
|
SAFE_NAME_CHANGE_TX: string,
|
||||||
OWNER_NAME_CHANGE_TX: string,
|
OWNER_NAME_CHANGE_TX: string,
|
||||||
THRESHOLD_CHANGE_TX: string,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const TX_NOTIFICATION_TYPES: NotifiedTransaction = {
|
export const TX_NOTIFICATION_TYPES: NotifiedTransaction = {
|
||||||
STANDARD_TX: 'STANDARD_TX',
|
STANDARD_TX: 'STANDARD_TX',
|
||||||
CONFIRMATION_TX: 'CONFIRMATION_TX',
|
CONFIRMATION_TX: 'CONFIRMATION_TX',
|
||||||
CANCELLATION_TX: 'CANCELLATION_TX',
|
CANCELLATION_TX: 'CANCELLATION_TX',
|
||||||
OWNER_CHANGE_TX: 'OWNER_CHANGE_TX',
|
SETTINGS_CHANGE_TX: 'SETTINGS_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',
|
||||||
THRESHOLD_CHANGE_TX: 'THRESHOLD_CHANGE_TX',
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,9 +4,8 @@ import { ETHEREUM_NETWORK_IDS, ETHEREUM_NETWORK, getProviderInfo } from '~/logic
|
||||||
import { getNetwork } from '~/config'
|
import { getNetwork } from '~/config'
|
||||||
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 { NOTIFICATIONS, showSnackbar, enhanceSnackbarForAction } from '~/logic/notifications'
|
import { NOTIFICATIONS, enhanceSnackbarForAction } from '~/logic/notifications'
|
||||||
import enqueueSnackbar from '~/logic/notifications/store/actions/enqueueSnackbar'
|
import enqueueSnackbar from '~/logic/notifications/store/actions/enqueueSnackbar'
|
||||||
import closeSnackbar from '~/logic/notifications/store/actions/closeSnackbar'
|
|
||||||
|
|
||||||
import addProvider from './addProvider'
|
import addProvider from './addProvider'
|
||||||
|
|
||||||
|
@ -35,7 +34,7 @@ const handleProviderNotification = (provider: ProviderProps, dispatch: Function)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ETHEREUM_NETWORK_IDS[network] !== getNetwork()) {
|
if (ETHEREUM_NETWORK_IDS[network] !== getNetwork()) {
|
||||||
dispatch(enqueueSnackbar(enhanceSnackbarForAction(NOTIFICATIONS.WRONG_NETWORK_MSG)))
|
dispatch(enqueueSnackbar(NOTIFICATIONS.WRONG_NETWORK_MSG))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (ETHEREUM_NETWORK.RINKEBY === getNetwork()) {
|
if (ETHEREUM_NETWORK.RINKEBY === getNetwork()) {
|
||||||
|
|
|
@ -2,9 +2,10 @@
|
||||||
import type { Store, AnyAction } from 'redux'
|
import type { Store, AnyAction } from 'redux'
|
||||||
import { type GlobalState } from '~/store/'
|
import { type GlobalState } from '~/store/'
|
||||||
import { ADD_PROVIDER, REMOVE_PROVIDER } from '../actions'
|
import { ADD_PROVIDER, REMOVE_PROVIDER } from '../actions'
|
||||||
import { getWeb3, getProviderInfo } from '~/logic/wallets/getWeb3'
|
import { getWeb3, getProviderInfo, WALLET_PROVIDER } from '~/logic/wallets/getWeb3'
|
||||||
import { fetchProvider } from '~/logic/wallets/store/actions'
|
import { fetchProvider } from '~/logic/wallets/store/actions'
|
||||||
import { loadFromStorage, saveToStorage, removeFromStorage } from '~/utils/storage'
|
import { loadFromStorage, saveToStorage, removeFromStorage } from '~/utils/storage'
|
||||||
|
import closeSnackbar from '~/logic/notifications/store/actions/closeSnackbar'
|
||||||
|
|
||||||
const watchedActions = [ADD_PROVIDER, REMOVE_PROVIDER]
|
const watchedActions = [ADD_PROVIDER, REMOVE_PROVIDER]
|
||||||
|
|
||||||
|
@ -30,17 +31,24 @@ const providerWatcherMware = (store: Store<GlobalState>) => (next: Function) =>
|
||||||
clearInterval(watcherInterval)
|
clearInterval(watcherInterval)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (currentProviderProps.name === WALLET_PROVIDER.METAMASK && window.ethereum) {
|
||||||
|
window.ethereum.autoRefreshOnNetworkChange = false
|
||||||
|
}
|
||||||
|
|
||||||
saveToStorage(LAST_USED_PROVIDER_KEY, currentProviderProps.name)
|
saveToStorage(LAST_USED_PROVIDER_KEY, currentProviderProps.name)
|
||||||
|
|
||||||
watcherInterval = setInterval(async () => {
|
watcherInterval = setInterval(async () => {
|
||||||
const web3 = getWeb3()
|
const web3 = getWeb3()
|
||||||
const providerInfo = await getProviderInfo(web3)
|
const providerInfo = await getProviderInfo(web3)
|
||||||
|
|
||||||
if (
|
const networkChanged = currentProviderProps.network !== providerInfo.network
|
||||||
currentProviderProps.account !== providerInfo.account
|
|
||||||
|| currentProviderProps.network !== providerInfo.network
|
if (networkChanged) {
|
||||||
) {
|
store.dispatch(closeSnackbar({ dismissAll: true }))
|
||||||
store.dispatch(fetchProvider(web3, () => {}, () => {}))
|
}
|
||||||
|
|
||||||
|
if (currentProviderProps.account !== providerInfo.account || networkChanged) {
|
||||||
|
store.dispatch(fetchProvider(web3))
|
||||||
}
|
}
|
||||||
}, 2000)
|
}, 2000)
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,7 @@ const ChangeSafeName = (props: Props) => {
|
||||||
updateSafe({ address: safeAddress, name: values.safeName })
|
updateSafe({ address: safeAddress, name: values.safeName })
|
||||||
|
|
||||||
const notification = getNotificationsFromTxType(TX_NOTIFICATION_TYPES.SAFE_NAME_CHANGE_TX)
|
const notification = getNotificationsFromTxType(TX_NOTIFICATION_TYPES.SAFE_NAME_CHANGE_TX)
|
||||||
showSnackbar(notification.afterExecution, enqueueSnackbar, closeSnackbar)
|
showSnackbar(notification.afterExecution.noMoreConfirmationsNeeded, enqueueSnackbar, closeSnackbar)
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -52,7 +52,7 @@ export const sendAddOwner = async (
|
||||||
safeAddress,
|
safeAddress,
|
||||||
0,
|
0,
|
||||||
txData,
|
txData,
|
||||||
TX_NOTIFICATION_TYPES.OWNER_CHANGE_TX,
|
TX_NOTIFICATION_TYPES.SETTINGS_CHANGE_TX,
|
||||||
enqueueSnackbar,
|
enqueueSnackbar,
|
||||||
closeSnackbar,
|
closeSnackbar,
|
||||||
)
|
)
|
||||||
|
|
|
@ -61,7 +61,7 @@ const ThresholdForm = ({
|
||||||
</Row>
|
</Row>
|
||||||
<Row>
|
<Row>
|
||||||
<Paragraph weight="bolder">
|
<Paragraph weight="bolder">
|
||||||
Any transaction over any daily limit requires the confirmation of:
|
Any transaction requires the confirmation of:
|
||||||
</Paragraph>
|
</Paragraph>
|
||||||
</Row>
|
</Row>
|
||||||
<Row margin="xl" align="center" className={classes.inputRow}>
|
<Row margin="xl" align="center" className={classes.inputRow}>
|
||||||
|
|
|
@ -52,7 +52,7 @@ const EditOwnerComponent = ({
|
||||||
editSafeOwner({ safeAddress, ownerAddress, ownerName: values.ownerName })
|
editSafeOwner({ safeAddress, ownerAddress, ownerName: values.ownerName })
|
||||||
|
|
||||||
const notification = getNotificationsFromTxType(TX_NOTIFICATION_TYPES.OWNER_NAME_CHANGE_TX)
|
const notification = getNotificationsFromTxType(TX_NOTIFICATION_TYPES.OWNER_NAME_CHANGE_TX)
|
||||||
showSnackbar(notification.afterExecution, enqueueSnackbar, closeSnackbar)
|
showSnackbar(notification.afterExecution.noMoreConfirmationsNeeded, enqueueSnackbar, closeSnackbar)
|
||||||
|
|
||||||
onClose()
|
onClose()
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,7 +64,7 @@ export const sendRemoveOwner = async (
|
||||||
safeAddress,
|
safeAddress,
|
||||||
0,
|
0,
|
||||||
txData,
|
txData,
|
||||||
TX_NOTIFICATION_TYPES.OWNER_CHANGE_TX,
|
TX_NOTIFICATION_TYPES.SETTINGS_CHANGE_TX,
|
||||||
enqueueSnackbar,
|
enqueueSnackbar,
|
||||||
closeSnackbar,
|
closeSnackbar,
|
||||||
)
|
)
|
||||||
|
|
|
@ -65,7 +65,7 @@ const ThresholdForm = ({
|
||||||
</Row>
|
</Row>
|
||||||
<Row>
|
<Row>
|
||||||
<Paragraph weight="bolder">
|
<Paragraph weight="bolder">
|
||||||
Any transaction over any daily limit requires the confirmation of:
|
Any transaction requires the confirmation of:
|
||||||
</Paragraph>
|
</Paragraph>
|
||||||
</Row>
|
</Row>
|
||||||
<Row margin="xl" align="center" className={classes.inputRow}>
|
<Row margin="xl" align="center" className={classes.inputRow}>
|
||||||
|
|
|
@ -60,7 +60,7 @@ export const sendReplaceOwner = async (
|
||||||
safeAddress,
|
safeAddress,
|
||||||
0,
|
0,
|
||||||
txData,
|
txData,
|
||||||
TX_NOTIFICATION_TYPES.OWNER_CHANGE_TX,
|
TX_NOTIFICATION_TYPES.SETTINGS_CHANGE_TX,
|
||||||
enqueueSnackbar,
|
enqueueSnackbar,
|
||||||
closeSnackbar,
|
closeSnackbar,
|
||||||
)
|
)
|
||||||
|
|
|
@ -162,33 +162,35 @@ class ManageOwners extends React.Component<Props, State> {
|
||||||
</TableCell>
|
</TableCell>
|
||||||
))}
|
))}
|
||||||
<TableCell component="td">
|
<TableCell component="td">
|
||||||
{granted && (
|
<Row align="end" className={classes.actions}>
|
||||||
<Row align="end" className={classes.actions}>
|
<Img
|
||||||
<Img
|
alt="Edit owner"
|
||||||
alt="Edit owner"
|
className={classes.editOwnerIcon}
|
||||||
className={classes.editOwnerIcon}
|
src={RenameOwnerIcon}
|
||||||
src={RenameOwnerIcon}
|
onClick={this.onShow('EditOwner', row)}
|
||||||
onClick={this.onShow('EditOwner', row)}
|
testId={RENAME_OWNER_BTN_TEST_ID}
|
||||||
testId={RENAME_OWNER_BTN_TEST_ID}
|
/>
|
||||||
/>
|
{granted && (
|
||||||
<Img
|
<>
|
||||||
alt="Replace owner"
|
|
||||||
className={classes.replaceOwnerIcon}
|
|
||||||
src={ReplaceOwnerIcon}
|
|
||||||
onClick={this.onShow('ReplaceOwner', row)}
|
|
||||||
testId={REPLACE_OWNER_BTN_TEST_ID}
|
|
||||||
/>
|
|
||||||
{ownerData.size > 1 && (
|
|
||||||
<Img
|
<Img
|
||||||
alt="Remove owner"
|
alt="Replace owner"
|
||||||
className={classes.removeOwnerIcon}
|
className={classes.replaceOwnerIcon}
|
||||||
src={RemoveOwnerIcon}
|
src={ReplaceOwnerIcon}
|
||||||
onClick={this.onShow('RemoveOwner', row)}
|
onClick={this.onShow('ReplaceOwner', row)}
|
||||||
testId={REMOVE_OWNER_BTN_TEST_ID}
|
testId={REPLACE_OWNER_BTN_TEST_ID}
|
||||||
/>
|
/>
|
||||||
)}
|
{ownerData.size > 1 && (
|
||||||
</Row>
|
<Img
|
||||||
)}
|
alt="Remove owner"
|
||||||
|
className={classes.removeOwnerIcon}
|
||||||
|
src={RemoveOwnerIcon}
|
||||||
|
onClick={this.onShow('RemoveOwner', row)}
|
||||||
|
testId={REMOVE_OWNER_BTN_TEST_ID}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
) }
|
||||||
|
</Row>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
))}
|
))}
|
||||||
|
|
|
@ -85,12 +85,6 @@ const ChangeThreshold = ({
|
||||||
{() => (
|
{() => (
|
||||||
<>
|
<>
|
||||||
<Block className={classes.modalContent}>
|
<Block className={classes.modalContent}>
|
||||||
<Row>
|
|
||||||
<Paragraph>
|
|
||||||
Every transaction outside any specified daily limits, needs to be confirmed by all specified owners.
|
|
||||||
If no daily limits are set, all owners will need to sign for transactions.
|
|
||||||
</Paragraph>
|
|
||||||
</Row>
|
|
||||||
<Row>
|
<Row>
|
||||||
<Paragraph weight="bolder">Any transaction requires the confirmation of:</Paragraph>
|
<Paragraph weight="bolder">Any transaction requires the confirmation of:</Paragraph>
|
||||||
</Row>
|
</Row>
|
||||||
|
|
|
@ -52,7 +52,7 @@ const ThresholdSettings = ({
|
||||||
safeAddress,
|
safeAddress,
|
||||||
0,
|
0,
|
||||||
txData,
|
txData,
|
||||||
TX_NOTIFICATION_TYPES.THRESHOLD_CHANGE_TX,
|
TX_NOTIFICATION_TYPES.SETTINGS_CHANGE_TX,
|
||||||
enqueueSnackbar,
|
enqueueSnackbar,
|
||||||
closeSnackbar,
|
closeSnackbar,
|
||||||
)
|
)
|
||||||
|
|
|
@ -15,12 +15,7 @@ import {
|
||||||
TX_TYPE_EXECUTION,
|
TX_TYPE_EXECUTION,
|
||||||
saveTxToHistory,
|
saveTxToHistory,
|
||||||
} from '~/logic/safe/transactions'
|
} from '~/logic/safe/transactions'
|
||||||
import {
|
import { type NotificationsQueue, getNotificationsFromTxType, showSnackbar } from '~/logic/notifications'
|
||||||
type Notification,
|
|
||||||
type NotificationsQueue,
|
|
||||||
getNotificationsFromTxType,
|
|
||||||
showSnackbar,
|
|
||||||
} from '~/logic/notifications'
|
|
||||||
import { getErrorMessage } from '~/test/utils/ethereumErrors'
|
import { getErrorMessage } from '~/test/utils/ethereumErrors'
|
||||||
import { ZERO_ADDRESS } from '~/logic/wallets/ethAddresses'
|
import { ZERO_ADDRESS } from '~/logic/wallets/ethAddresses'
|
||||||
import { SAFELIST_ADDRESS } from '~/routes/routes'
|
import { SAFELIST_ADDRESS } from '~/routes/routes'
|
||||||
|
@ -75,16 +70,8 @@ const createTransaction = (
|
||||||
.once('transactionHash', async (hash) => {
|
.once('transactionHash', async (hash) => {
|
||||||
txHash = hash
|
txHash = hash
|
||||||
closeSnackbar(beforeExecutionKey)
|
closeSnackbar(beforeExecutionKey)
|
||||||
const pendingExecutionNotification: Notification = isExecution
|
|
||||||
? {
|
pendingExecutionKey = showSnackbar(notificationsQueue.pendingExecution, enqueueSnackbar, closeSnackbar)
|
||||||
message: notificationsQueue.pendingExecution.noMoreConfirmationsNeeded.message,
|
|
||||||
options: notificationsQueue.pendingExecution.noMoreConfirmationsNeeded.options,
|
|
||||||
}
|
|
||||||
: {
|
|
||||||
message: notificationsQueue.pendingExecution.moreConfirmationsNeeded.message,
|
|
||||||
options: notificationsQueue.pendingExecution.moreConfirmationsNeeded.options,
|
|
||||||
}
|
|
||||||
pendingExecutionKey = showSnackbar(pendingExecutionNotification, enqueueSnackbar, closeSnackbar)
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await saveTxToHistory(
|
await saveTxToHistory(
|
||||||
|
@ -108,9 +95,14 @@ const createTransaction = (
|
||||||
.then((receipt) => {
|
.then((receipt) => {
|
||||||
closeSnackbar(pendingExecutionKey)
|
closeSnackbar(pendingExecutionKey)
|
||||||
|
|
||||||
if (isExecution) {
|
showSnackbar(
|
||||||
showSnackbar(notificationsQueue.afterExecution, enqueueSnackbar, closeSnackbar)
|
isExecution
|
||||||
}
|
? notificationsQueue.afterExecution.noMoreConfirmationsNeeded
|
||||||
|
: notificationsQueue.afterExecution.moreConfirmationsNeeded,
|
||||||
|
enqueueSnackbar,
|
||||||
|
closeSnackbar,
|
||||||
|
)
|
||||||
|
|
||||||
dispatch(fetchTransactions(safeAddress))
|
dispatch(fetchTransactions(safeAddress))
|
||||||
|
|
||||||
return receipt.transactionHash
|
return receipt.transactionHash
|
||||||
|
|
|
@ -17,7 +17,6 @@ import {
|
||||||
TX_TYPE_CONFIRMATION,
|
TX_TYPE_CONFIRMATION,
|
||||||
} from '~/logic/safe/transactions'
|
} from '~/logic/safe/transactions'
|
||||||
import {
|
import {
|
||||||
type Notification,
|
|
||||||
type NotificationsQueue,
|
type NotificationsQueue,
|
||||||
getNotificationsFromTxType,
|
getNotificationsFromTxType,
|
||||||
showSnackbar,
|
showSnackbar,
|
||||||
|
@ -107,11 +106,8 @@ const processTransaction = (
|
||||||
.once('transactionHash', async (hash) => {
|
.once('transactionHash', async (hash) => {
|
||||||
txHash = hash
|
txHash = hash
|
||||||
closeSnackbar(beforeExecutionKey)
|
closeSnackbar(beforeExecutionKey)
|
||||||
const notification: Notification = {
|
|
||||||
message: notificationsQueue.pendingExecution.noMoreConfirmationsNeeded.message,
|
pendingExecutionKey = showSnackbar(notificationsQueue.pendingExecution, enqueueSnackbar, closeSnackbar)
|
||||||
options: notificationsQueue.pendingExecution.noMoreConfirmationsNeeded.options,
|
|
||||||
}
|
|
||||||
pendingExecutionKey = showSnackbar(notification, enqueueSnackbar, closeSnackbar)
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await saveTxToHistory(
|
await saveTxToHistory(
|
||||||
|
@ -135,7 +131,13 @@ const processTransaction = (
|
||||||
.then((receipt) => {
|
.then((receipt) => {
|
||||||
closeSnackbar(pendingExecutionKey)
|
closeSnackbar(pendingExecutionKey)
|
||||||
|
|
||||||
showSnackbar(notificationsQueue.afterExecution, enqueueSnackbar, closeSnackbar)
|
showSnackbar(
|
||||||
|
shouldExecute
|
||||||
|
? notificationsQueue.afterExecution.noMoreConfirmationsNeeded
|
||||||
|
: notificationsQueue.afterExecution.moreConfirmationsNeeded,
|
||||||
|
enqueueSnackbar,
|
||||||
|
closeSnackbar,
|
||||||
|
)
|
||||||
dispatch(fetchTransactions(safeAddress))
|
dispatch(fetchTransactions(safeAddress))
|
||||||
|
|
||||||
return receipt.transactionHash
|
return receipt.transactionHash
|
||||||
|
|
Loading…
Reference in New Issue