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

Release v2.19.0 #1828

Merged
merged 25 commits into from
Feb 2, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
1a50b59
Bug: Use link tag instead of javascript navigation in apps list (#1770)
mmv08 Jan 13, 2021
188dc80
Fix asset value column alignment (#1778)
alongoni Jan 15, 2021
dfc650d
Merge branch 'development' into release/v2.18.0
Jan 19, 2021
46274b0
fix ids (#1755)
francovenica Jan 19, 2021
d36e447
Merge branch 'development' into release/v2.18.0
Jan 19, 2021
8747095
Merge pull request #1796 from gnosis/release/v2.18.0
Jan 19, 2021
3748245
Merge branch 'development' into hotfix/refund-displayed-as-rejection
Jan 22, 2021
5e57368
Merge pull request #1807 from gnosis/hotfix/refund-displayed-as-rejec…
Jan 25, 2021
19be231
(Fix) - #1804 Tx gas estimation fail for threshold >= 3 (#1808)
Agupane Jan 26, 2021
a020e8e
(Fix) - Gas estimation for transaction creation (#1772)
Agupane Jan 26, 2021
fef88b0
Update 1 Inch app to v1.2.3 (#1816)
Jan 27, 2021
57f7acd
Update IDLE Safe app (#1813)
Jan 27, 2021
d6343a9
Feature: Single tx safe apps interactions should not use multisend (#…
mmv08 Jan 27, 2021
621401b
Add dHedge safe app (#1821)
Jan 27, 2021
e3adb24
Update balancer pool management app with new keys (#1819)
Jan 27, 2021
3d43db0
(Fix) Contract interaction tuples (#1787)
Agupane Jan 27, 2021
758fc3c
(Fix) Estimate gas for wallet connect (#1806)
Agupane Jan 28, 2021
6b4b156
Update balancer exchange app (#1823)
Jan 28, 2021
012b41a
Feature - Add .crypto domain resolution (#1764)
Jan 29, 2021
3415b73
Update WalletConnect app url (#1822)
mmv08 Jan 29, 2021
2ea67b5
Set transaction parameters manually - Advanced options (#1760)
nicosampler Jan 29, 2021
2bd73c3
Set v2.19.0
Feb 1, 2021
4bf1a74
fix 'Advanced options' presentation in modal
alongoni Feb 1, 2021
42821c1
Avoids changing the transaction fee message while loading the estimation
alongoni Feb 1, 2021
2955985
Fix multisend enconding when adding a new spender to allowance module
Feb 2, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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