From cafbfb38d973a061eb2a0a638f9867ff41a8bd5b Mon Sep 17 00:00:00 2001 From: apanizo Date: Wed, 14 Nov 2018 12:45:10 +0100 Subject: [PATCH] Calculating isOwner property in ReviewInfo component #75 --- src/routes/load/components/Layout.jsx | 11 +- .../components/ReviewInformation/index.jsx | 122 ++++++++++++------ src/routes/load/container/Load.jsx | 13 +- src/routes/load/container/selector.js | 17 ++- 4 files changed, 107 insertions(+), 56 deletions(-) diff --git a/src/routes/load/components/Layout.jsx b/src/routes/load/components/Layout.jsx index 65c3241c..95beb9c9 100644 --- a/src/routes/load/components/Layout.jsx +++ b/src/routes/load/components/Layout.jsx @@ -1,5 +1,6 @@ // @flow import * as React from 'react' +import ChevronLeft from '@material-ui/icons/ChevronLeft' import Stepper from '~/components/Stepper' import Block from '~/components/layout/Block' import Heading from '~/components/layout/Heading' @@ -7,17 +8,15 @@ import Row from '~/components/layout/Row' import IconButton from '@material-ui/core/IconButton' import ReviewInformation from '~/routes/load/components/ReviewInformation' import DetailsForm, { safeFieldsValidation } from '~/routes/load/components/DetailsForm' -import ChevronLeft from '@material-ui/icons/ChevronLeft' import { history } from '~/store' import { secondary } from '~/theme/variables' +import { type SelectorProps } from '~/routes/load/container/selector' const getSteps = () => [ 'Details', 'Review', ] -type Props = { - provider: string, - network: string, +type Props = SelectorProps & { onLoadSafeSubmit: (values: Object) => Promise, } @@ -32,7 +31,7 @@ const back = () => { } const Layout = ({ - provider, onLoadSafeSubmit, network, + provider, onLoadSafeSubmit, network, userAddress, }: Props) => { const steps = getSteps() @@ -54,7 +53,7 @@ const Layout = ({ { DetailsForm } - + { ReviewInformation } diff --git a/src/routes/load/components/ReviewInformation/index.jsx b/src/routes/load/components/ReviewInformation/index.jsx index 935016c1..1790e910 100644 --- a/src/routes/load/components/ReviewInformation/index.jsx +++ b/src/routes/load/components/ReviewInformation/index.jsx @@ -8,8 +8,10 @@ import OpenPaper from '~/components/Stepper/OpenPaper' import Row from '~/components/layout/Row' import Paragraph from '~/components/layout/Paragraph' import { xs, sm, lg, border, secondary } from '~/theme/variables' -import { openAddressInEtherScan } from '~/logic/wallets/getWeb3' +import { openAddressInEtherScan, getWeb3 } from '~/logic/wallets/getWeb3' import { FIELD_LOAD_NAME, FIELD_LOAD_ADDRESS } from '~/routes/load/components/fields' +import { sameAddress } from '~/logic/wallets/ethAddresses' +import { getGnosisSafeContract } from '~/logic/contracts/safeContracts' const openIconStyle = { height: '16px', @@ -43,6 +45,7 @@ const styles = () => ({ type LayoutProps = { network: string, + userAddress: string, } type Props = LayoutProps & { @@ -50,53 +53,92 @@ type Props = LayoutProps & { classes: Object, } -const ReviewComponent = ({ values, classes, network }: Props) => { - const safeAddress = values[FIELD_LOAD_ADDRESS] +type State = { + isOwner: boolean, +} - return ( - - - - - Name of the Safe - - - {values[FIELD_LOAD_NAME]} - +class ReviewComponent extends React.PureComponent { + state = { + isOwner: false, + } + + componentDidMount = async () => { + this.mounted = true + + const { values, userAddress } = this.props + const safeAddress = values[FIELD_LOAD_ADDRESS] + const web3 = getWeb3() + + const GnosisSafe = getGnosisSafeContract(web3) + const gnosisSafe = GnosisSafe.at(safeAddress) + const owners = await gnosisSafe.getOwners() + if (!owners) { + return + } + + const isOwner = owners.find((owner: string) => sameAddress(owner, userAddress)) !== undefined + if (this.mounted) { + this.setState(() => ({ isOwner })) + } + } + + componentWillUnmount() { + this.mounted = false + } + + mounted = false + + render() { + const { values, classes, network } = this.props + const { isOwner } = this.state + + const safeAddress = values[FIELD_LOAD_ADDRESS] + + return ( + + + + + Name of the Safe + + + {values[FIELD_LOAD_NAME]} + + + + + Safe address + + + + {safeAddress} + + + + + + Connected wallet client is owner? + + + { isOwner ? 'Yes' : 'No (read-only)' } + + - - - Safe address - - - - {safeAddress} - - - - - - Connected wallet client is owner? - - - No (read-only) - - - - - ) + + ) + } } const ReviewPage = withStyles(styles)(ReviewComponent) -const Review = ({ network }: LayoutProps) => (controls: React$Node, { values }: Object) => ( +const Review = ({ network, userAddress }: LayoutProps) => (controls: React$Node, { values }: Object) => ( - + ) diff --git a/src/routes/load/container/Load.jsx b/src/routes/load/container/Load.jsx index 3997f819..27f3e96e 100644 --- a/src/routes/load/container/Load.jsx +++ b/src/routes/load/container/Load.jsx @@ -6,16 +6,12 @@ import { buildSafe } from '~/routes/safe/store/actions/fetchSafe' import { SAFES_KEY, load, saveSafes } from '~/utils/localStorage' import { SAFELIST_ADDRESS } from '~/routes/routes' import { history } from '~/store' -import selector from './selector' +import selector, { type SelectorProps } from './selector' import actions, { type Actions, type UpdateSafe } from './actions' import Layout from '../components/Layout' import { FIELD_LOAD_NAME, FIELD_LOAD_ADDRESS } from '../components/fields' -type Props = Actions & { - provider: string, - userAccount: string, - network: string, -} +type Props = SelectorProps & Actions export const loadSafe = async (safeName: string, safeAddress: string, updateSafe: UpdateSafe) => { const safeRecord = await buildSafe(safeAddress, safeName) @@ -45,7 +41,9 @@ class Open extends React.Component { } render() { - const { provider, network } = this.props + const { + provider, network, userAddress, + } = this.props return ( @@ -53,6 +51,7 @@ class Open extends React.Component { network={network} provider={provider} onLoadSafeSubmit={this.onLoadSafeSubmit} + userAddress={userAddress} /> ) diff --git a/src/routes/load/container/selector.js b/src/routes/load/container/selector.js index 658cc2a4..28f673b9 100644 --- a/src/routes/load/container/selector.js +++ b/src/routes/load/container/selector.js @@ -1,8 +1,19 @@ // @flow -import { createStructuredSelector } from 'reselect' -import { providerNameSelector, networkSelector } from '~/logic/wallets/store/selectors' +import { createStructuredSelector, type Selector } from 'reselect' +import { providerNameSelector, networkSelector, userAccountSelector } from '~/logic/wallets/store/selectors' +import { type GlobalState } from '~/store' -export default createStructuredSelector({ +export type SelectorProps = { + provider: string, + network: string, + userAddress: string, +} + +const structuredSelector: Selector = createStructuredSelector({ provider: providerNameSelector, network: networkSelector, + userAddress: userAccountSelector, }) + +export default structuredSelector +