Skip to content
This repository has been archived by the owner on Nov 10, 2023. It is now read-only.

Commit

Permalink
Merge pull request #1828 from gnosis/release/v2.19.0
Browse files Browse the repository at this point in the history
Release v2.19.0
  • Loading branch information
Daniel Sanchez authored Feb 2, 2021
2 parents 173054a + 2955985 commit 2f6113d
Show file tree
Hide file tree
Showing 87 changed files with 3,769 additions and 1,661 deletions.
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ matrix:
- REACT_APP_SENTRY_DSN=${SENTRY_DSN_VOLTA}
- SENTRY_PROJECT=${SENTRY_PROJECT_VOLTA}
- REACT_APP_GOOGLE_ANALYTICS=${REACT_APP_GOOGLE_ANALYTICS_ID_VOLTA}
if: (branch = master) OR tag IS present
- env:
- REACT_APP_NETWORK='energy_web_chain'
- STAGING_BUCKET_NAME=${STAGING_EWC_BUCKET_NAME}
Expand Down
2 changes: 1 addition & 1 deletion docs/networks.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ export enum FEATURES {
ERC1155 = 'ERC1155',
SAFE_APPS = 'SAFE_APPS',
CONTRACT_INTERACTION = 'CONTRACT_INTERACTION',
ENS_LOOKUP = 'ENS_LOOKUP'
DOMAIN_LOOKUP = 'DOMAIN_LOOKUP'
}
```

Expand Down
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "safe-react",
"version": "2.18.1",
"version": "2.19.0",
"description": "Allowing crypto users manage funds in a safer way",
"website": "https://github.com/gnosis/safe-react#readme",
"bugs": {
Expand Down Expand Up @@ -161,7 +161,7 @@
"@gnosis.pm/safe-apps-sdk": "1.0.2",
"@gnosis.pm/safe-apps-sdk-v1": "npm:@gnosis.pm/[email protected]",
"@gnosis.pm/safe-contracts": "1.1.1-dev.2",
"@gnosis.pm/safe-react-components": "https://github.com/gnosis/safe-react-components.git#bf3a84486b7353bd25447ddff39c406f6fafecc6",
"@gnosis.pm/safe-react-components": "https://github.com/gnosis/safe-react-components.git#2e7574f",
"@gnosis.pm/util-contracts": "2.0.6",
"@ledgerhq/hw-transport-node-hid-singleton": "5.38.0",
"@material-ui/core": "^4.11.0",
Expand All @@ -170,6 +170,7 @@
"@openzeppelin/contracts": "3.1.0",
"@sentry/react": "^5.28.0",
"@sentry/tracing": "^5.28.0",
"@unstoppabledomains/resolution": "^1.11.1",
"@truffle/contract": "^4.3.0",
"async-sema": "^3.1.0",
"axios": "0.21.1",
Expand Down
2 changes: 1 addition & 1 deletion src/components/AppLayout/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ const Layout: React.FC<Props> = ({
<Header />
</HeaderWrapper>
<BodyWrapper>
<SidebarWrapper>
<SidebarWrapper data-testid="sidebar">
<Sidebar
items={sidebarItems}
safeAddress={safeAddress}
Expand Down
9 changes: 4 additions & 5 deletions src/components/Modal/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,14 @@ const useStyles = makeStyles(
createStyles({
root: {
alignItems: 'center',
justifyContent: 'center',
flexDirection: 'column',
display: 'flex',
overflowY: 'scroll',
},
paper: {
position: 'absolute',
top: '120px',
position: 'relative',
top: '68px',
width: '500px',
height: '580px',
borderRadius: sm,
backgroundColor: '#ffffff',
boxShadow: '0 0 5px 0 rgba(74, 85, 121, 0.5)',
Expand Down Expand Up @@ -62,7 +61,7 @@ const GnoModal = ({
onClose={handleClose}
open={open}
>
<div className={cn(classes.paper, paperClassName)}>{children}</div>
<div className={cn(classes.paper, paperClassName, 'classpep')}>{children}</div>
</Modal>
)
}
Expand Down
44 changes: 36 additions & 8 deletions src/components/ModalTitle/index.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import React from 'react'
import styled from 'styled-components'
import IconButton from '@material-ui/core/IconButton'
import Close from '@material-ui/icons/Close'

import Paragraph from 'src/components/layout/Paragraph'
import { lg } from 'src/theme/variables'
import { md, lg } from 'src/theme/variables'
import Row from 'src/components/layout/Row'

const StyledParagraph = styled(Paragraph)`
&& {
Expand All @@ -18,14 +21,39 @@ const TitleWrapper = styled.div`
align-items: center;
`

const ModalTitle = ({ iconUrl, title }: { title: string; iconUrl: string }) => {
const StyledRow = styled(Row)`
padding: ${md} ${lg};
justify-content: space-between;
box-sizing: border-box;
max-height: 75px;
`

const StyledClose = styled(Close)`
height: 35px;
width: 35px;
`

const ModalTitle = ({
iconUrl,
title,
onClose,
}: {
title: string
iconUrl: string
onClose?: () => void
}): React.ReactElement => {
return (
<TitleWrapper>
{iconUrl && <IconImg alt={title} src={iconUrl} />}
<StyledParagraph noMargin weight="bolder">
{title}
</StyledParagraph>
</TitleWrapper>
<StyledRow align="center" grow>
<TitleWrapper>
{iconUrl && <IconImg alt={title} src={iconUrl} />}
<StyledParagraph noMargin weight="bolder">
{title}
</StyledParagraph>
</TitleWrapper>
<IconButton disableRipple onClick={onClose}>
<StyledClose />
</IconButton>
</StyledRow>
)
}

Expand Down
14 changes: 3 additions & 11 deletions src/components/TransactionsFees/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,6 @@ import { EstimationStatus } from 'src/logic/hooks/useEstimateTransactionGas'
import Paragraph from 'src/components/layout/Paragraph'
import { getNetworkInfo } from 'src/config'
import { TransactionFailText } from 'src/components/TransactionFailText'
import { useSelector } from 'react-redux'
import { providerNameSelector } from 'src/logic/wallets/store/selectors'
import { sameString } from 'src/utils/strings'
import { WALLETS } from 'src/config/networks/network.d'

type TransactionFailTextProps = {
txEstimationExecutionStatus: EstimationStatus
Expand All @@ -24,9 +20,10 @@ export const TransactionFees = ({
isOffChainSignature,
txEstimationExecutionStatus,
}: TransactionFailTextProps): React.ReactElement | null => {
const providerName = useSelector(providerNameSelector)

let transactionAction
if (txEstimationExecutionStatus === EstimationStatus.LOADING) {
return null
}
if (isCreation) {
transactionAction = 'create'
} else if (isExecution) {
Expand All @@ -35,11 +32,6 @@ export const TransactionFees = ({
transactionAction = 'approve'
}

// FIXME this should be removed when estimating with WalletConnect correctly
if (!providerName || sameString(providerName, WALLETS.WALLET_CONNECT)) {
return null
}

return (
<>
<Paragraph>
Expand Down
8 changes: 4 additions & 4 deletions src/components/forms/AddressInput/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import { OnChange } from 'react-final-form-listeners'
import TextField from 'src/components/forms/TextField'
import { Validator, composeValidators, mustBeEthereumAddress, required } from 'src/components/forms/validator'
import { trimSpaces } from 'src/utils/strings'
import { getAddressFromENS } from 'src/logic/wallets/getWeb3'
import { isValidEnsName } from 'src/logic/wallets/ethAddresses'
import { getAddressFromDomain } from 'src/logic/wallets/getWeb3'
import { isValidEnsName, isValidCryptoDomainName } from 'src/logic/wallets/ethAddresses'
import { checksumAddress } from 'src/utils/checksumAddress'

// an idea for second field was taken from here
Expand Down Expand Up @@ -54,9 +54,9 @@ const AddressInput = ({
<OnChange name={name}>
{async (value) => {
const address = trimSpaces(value)
if (isValidEnsName(address)) {
if (isValidEnsName(address) || isValidCryptoDomainName(address)) {
try {
const resolverAddr = await getAddressFromENS(address)
const resolverAddr = await getAddressFromDomain(address)
const formattedAddress = checksumAddress(resolverAddr)
fieldMutator(formattedAddress)
} catch (err) {
Expand Down
140 changes: 84 additions & 56 deletions src/components/forms/TextField/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import MuiTextField from '@material-ui/core/TextField'
import { withStyles } from '@material-ui/core/styles'
import { createStyles, makeStyles } from '@material-ui/core/styles'
import React from 'react'

import { lg } from 'src/theme/variables'
Expand All @@ -10,65 +10,93 @@ const overflowStyle = {
width: '100%',
}

const styles = () => ({
root: {
paddingTop: lg,
paddingBottom: '12px',
lineHeight: 0,
},
})
const styles = () =>
createStyles({
root: {
paddingTop: lg,
paddingBottom: '12px',
lineHeight: 0,
},
})

class TextField extends React.PureComponent<any> {
render() {
const {
classes,
input: { name, onChange, value, ...restInput },
inputAdornment,
meta,
multiline,
rows,
testId,
text,
...rest
} = this.props
const helperText = value ? text : undefined
const showError = (meta.touched || !meta.pristine) && !meta.valid
const hasError = !!meta.error || (!meta.modifiedSinceLastSubmit && !!meta.submitError)
const errorMessage = meta.error || meta.submitError
const isInactiveAndPristineOrUntouched = !meta.active && (meta.pristine || !meta.touched)
const isInvalidAndUntouched = typeof meta.error === 'undefined' ? true : !meta.touched
const useStyles = makeStyles(styles)

const disableUnderline = isInactiveAndPristineOrUntouched && isInvalidAndUntouched
type Props = {
input: {
name: string
onChange?: () => void
value: string
placeholder: string
type: string
}
meta: {
touched?: boolean
pristine?: boolean
valid?: boolean
error?: string
modifiedSinceLastSubmit?: boolean
submitError?: boolean
active?: boolean
}
inputAdornment?: { endAdornment: React.ReactElement } | undefined
multiline: boolean
rows?: string
testId: string
text: string
disabled?: boolean
rowsMax?: number
className?: string
}

const inputRoot = helperText ? classes.root : ''
const statusClasses = meta.valid ? 'isValid' : hasError && showError ? 'isInvalid' : ''
const inputProps = {
...restInput,
autoComplete: 'off',
'data-testid': testId,
}
const inputRootProps = {
...inputAdornment,
className: `${inputRoot} ${statusClasses}`,
disableUnderline: disableUnderline,
}
const TextField = (props: Props): React.ReactElement => {
const {
input: { name, onChange, value, ...restInput },
inputAdornment,
meta,
multiline,
rows,
testId,
text,
...rest
} = props
const classes = useStyles()
const helperText = value ? text : undefined
const showError = (meta.touched || !meta.pristine) && !meta.valid
const hasError = !!meta.error || (!meta.modifiedSinceLastSubmit && !!meta.submitError)
const errorMessage = meta.error || meta.submitError
const isInactiveAndPristineOrUntouched = !meta.active && (meta.pristine || !meta.touched)
const isInvalidAndUntouched = typeof meta.error === 'undefined' ? true : !meta.touched

return (
<MuiTextField
error={hasError && showError}
helperText={hasError && showError ? errorMessage : helperText || ' '}
inputProps={inputProps} // blank in order to force to have helper text
InputProps={inputRootProps}
multiline={multiline}
name={name}
onChange={onChange}
rows={rows}
style={overflowStyle}
value={value}
{...rest}
/>
)
const disableUnderline = isInactiveAndPristineOrUntouched && isInvalidAndUntouched

const inputRoot = helperText ? classes.root : ''
const statusClasses = meta.valid ? 'isValid' : hasError && showError ? 'isInvalid' : ''
const inputProps = {
...restInput,
autoComplete: 'off',
'data-testid': testId,
}
const inputRootProps = {
...inputAdornment,
className: `${inputRoot} ${statusClasses}`,
disableUnderline: disableUnderline,
}

return (
<MuiTextField
error={hasError && showError}
helperText={hasError && showError ? errorMessage : helperText || ' '}
inputProps={inputProps} // blank in order to force to have helper text
InputProps={inputRootProps}
multiline={multiline}
name={name}
onChange={onChange}
rows={rows}
style={overflowStyle}
value={value}
{...rest}
/>
)
}

export default withStyles(styles as any)(TextField)
export default TextField
2 changes: 1 addition & 1 deletion src/components/forms/validator.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ describe('Forms > Validators', () => {
})

describe('mustBeEthereumAddress validator', () => {
const MUST_BE_ETH_ADDRESS_ERR_MSG = 'Address should be a valid Ethereum address or ENS name'
const MUST_BE_ETH_ADDRESS_ERR_MSG = 'Input must be a valid Ethereum address, ENS or Unstoppable domain'

it('Returns undefined for a valid ethereum address', async () => {
expect(await mustBeEthereumAddress('0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe')).toBeUndefined()
Expand Down
12 changes: 8 additions & 4 deletions src/components/forms/validator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ export const mustBeUrl = (value: string): ValidatorReturnType => {
}

export const minValue = (min: number | string, inclusive = true) => (value: string): ValidatorReturnType => {
if (!value) {
return undefined
}

if (Number.parseFloat(value) > Number(min) || (inclusive && Number.parseFloat(value) >= Number(min))) {
return undefined
}
Expand All @@ -64,8 +68,8 @@ export const mustBeEthereumAddress = memoize(
const startsWith0x = address?.startsWith('0x')
const isAddress = getWeb3().utils.isAddress(address)

const errorMessage = `Address should be a valid Ethereum address${
isFeatureEnabled(FEATURES.ENS_LOOKUP) ? ' or ENS name' : ''
const errorMessage = `Input must be a valid Ethereum address${
isFeatureEnabled(FEATURES.DOMAIN_LOOKUP) ? ', ENS or Unstoppable domain' : ''
}`

return startsWith0x && isAddress ? undefined : errorMessage
Expand All @@ -76,8 +80,8 @@ export const mustBeEthereumContractAddress = memoize(
async (address: string): Promise<ValidatorReturnType> => {
const contractCode = await getWeb3().eth.getCode(address)

const errorMessage = `Address should be a valid Ethereum contract address${
isFeatureEnabled(FEATURES.ENS_LOOKUP) ? ' or ENS name' : ''
const errorMessage = `Input must be a valid Ethereum contract address${
isFeatureEnabled(FEATURES.DOMAIN_LOOKUP) ? ', ENS or Unstoppable domain' : ''
}`

return !contractCode || contractCode.replace('0x', '').replace(/0/g, '') === '' ? errorMessage : undefined
Expand Down
Loading

0 comments on commit 2f6113d

Please sign in to comment.