Merge branch 'development' into darwin-arm64-support

This commit is contained in:
Daniel Sanchez 2021-04-13 09:38:37 +02:00 committed by GitHub
commit aadf6b92f4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 84 additions and 99 deletions

View File

@ -1,6 +1,6 @@
{
"name": "safe-react",
"version": "3.3.1",
"version": "3.4.0",
"description": "Allowing crypto users manage funds in a safer way",
"website": "https://github.com/gnosis/safe-react#readme",
"bugs": {

View File

@ -3,7 +3,7 @@ import { EnvironmentSettings, ETHEREUM_NETWORK, NetworkConfig } from 'src/config
const baseConfig: EnvironmentSettings = {
clientGatewayUrl: 'https://safe-client.rinkeby.staging.gnosisdev.com/v1',
txServiceUrl: 'https://safe-transaction.staging.gnosisdev.com/api/v1',
txServiceUrl: 'https://safe-transaction.rinkeby.staging.gnosisdev.com/api/v1',
safeAppsUrl: 'https://safe-apps.dev.gnosisdev.com',
gasPriceOracle: {
url: 'https://ethgasstation.info/json/ethgasAPI.json',

View File

@ -36,8 +36,8 @@ const mainnet: NetworkConfig = {
isTestNet: true,
nativeCoin: {
address: '0x0000000000000000000000000000000000000000',
name: 'Energy web token',
symbol: 'EWT',
name: 'Volta Token',
symbol: 'VT',
decimals: 18,
logoUri: EwcLogo,
},

View File

@ -1,11 +1,9 @@
import axios from 'axios'
import { getSafeClientGatewayBaseUrl, getNetworkInfo } from 'src/config'
import { getSafeClientGatewayBaseUrl } from 'src/config'
import { TokenProps } from 'src/logic/tokens/store/model/token'
import { checksumAddress } from 'src/utils/checksumAddress'
import { ZERO_ADDRESS, sameAddress } from 'src/logic/wallets/ethAddresses'
export type TokenBalance = {
tokenInfo: TokenProps
balance: string
@ -35,24 +33,5 @@ export const fetchTokenCurrenciesBalances = async ({
checksumAddress(safeAddress),
)}/balances/${selectedCurrency}/?trusted=${trustedTokens}&exclude_spam=${excludeSpamTokens}`
return axios.get(url).then(({ data }) => {
// Currently the client-gateway is not returning the balance using network token symbol and name
// FIXME remove this logic and return data directly once this is fixed
const { nativeCoin } = getNetworkInfo()
if (data.items && data.items.length) {
data.items = data.items.map((element) => {
const { tokenInfo } = element
if (sameAddress(ZERO_ADDRESS, tokenInfo.address)) {
// If it's native coin we swap symbol and name
tokenInfo.symbol = nativeCoin.symbol
tokenInfo.name = nativeCoin.name
}
return element
})
}
return data
})
return axios.get(url).then(({ data }) => data)
}

View File

@ -28,10 +28,10 @@ export const useLoadSafe = (safeAddress?: string, loadedViaUrl = true): boolean
}
}
}
dispatch(loadAddressBookFromStorage())
dispatch(loadAddressBookFromStorage())
fetchData()
}, [dispatch, safeAddress])
}, [dispatch, safeAddress, loadedViaUrl])
return isSafeLoaded
}

View File

@ -133,7 +133,7 @@ type BaseCustom = {
dataSize: string
value: string
isCancellation: boolean
toInfo: AddressInfo
toInfo?: AddressInfo
}
type Custom = BaseCustom & {

View File

@ -17,7 +17,7 @@ const SIGNERS = {
const getSignersByWallet = (isHW) =>
isHW ? [SIGNERS.ETH_SIGN] : [SIGNERS.EIP712_V3, SIGNERS.EIP712_V4, SIGNERS.EIP712, SIGNERS.ETH_SIGN]
export const SAFE_VERSION_FOR_OFFCHAIN_SIGNATURES = '>=1.0.0'
export const SAFE_VERSION_FOR_OFFCHAIN_SIGNATURES = '>=1.1.1'
export const tryOffchainSigning = async (safeTxHash: string, txArgs, isHW: boolean): Promise<string> => {
let signature

View File

@ -255,7 +255,8 @@ const AddressBookTable = (): ReactElement => {
activeScreenType="chooseTxType"
isOpen={sendFundsModalOpen}
onClose={() => setSendFundsModalOpen(false)}
recipientAddress={selectedEntry && selectedEntry.entry ? selectedEntry.entry.address : undefined}
recipientAddress={selectedEntry?.entry?.address}
recipientName={selectedEntry?.entry?.name}
/>
</>
)

View File

@ -59,11 +59,12 @@ const StyledCard = styled(Card)`
padding: 0;
`
const StyledIframe = styled.iframe`
const StyledIframe = styled.iframe<{ isLoading: boolean }>`
height: 100%;
width: 100%;
overflow: auto;
box-sizing: border-box;
display: ${({ isLoading }) => (isLoading ? 'none' : 'block')};
`
const Breadcrumb = styled.div`
@ -326,6 +327,7 @@ const AppFrame = ({ appUrl }: Props): React.ReactElement => {
)}
<StyledIframe
isLoading={appIsLoading}
frameBorder="0"
id={`iframe-${appUrl}`}
ref={iframeRef}

View File

@ -34,12 +34,6 @@ export const staticAppsList: Array<StaticAppInfo> = [
disabled: false,
networks: [ETHEREUM_NETWORK.MAINNET],
},
// Aave v2
{
url: `${process.env.REACT_APP_IPFS_GATEWAY}/QmVg7aXr5S8sT2iUdUwdkfTJNknmB7rcE3t92HiGoVsYDj`,
disabled: false,
networks: [ETHEREUM_NETWORK.MAINNET],
},
//Balancer Exchange
{
url: `${process.env.REACT_APP_IPFS_GATEWAY}/QmRb2VfPVYBrv6gi2zDywgVgTg3A19ZCRMqwL13Ez5f5AS`,

View File

@ -56,6 +56,7 @@ type Props = {
isOpen: boolean
onClose: () => void
recipientAddress?: string
recipientName?: string
selectedToken?: string | NFTToken | Erc721Transfer
tokenAmount?: string
}
@ -65,6 +66,7 @@ const SendModal = ({
isOpen,
onClose,
recipientAddress,
recipientName,
selectedToken,
tokenAmount,
}: Props): React.ReactElement => {
@ -119,7 +121,12 @@ const SendModal = ({
}
>
{activeScreen === 'chooseTxType' && (
<ChooseTxType onClose={onClose} recipientAddress={recipientAddress} setActiveScreen={setActiveScreen} />
<ChooseTxType
onClose={onClose}
recipientName={recipientName}
recipientAddress={recipientAddress}
setActiveScreen={setActiveScreen}
/>
)}
{activeScreen === 'sendFunds' && (

View File

@ -14,20 +14,29 @@ import Row from 'src/components/layout/Row'
import { safeFeaturesEnabledSelector } from 'src/logic/safe/store/selectors'
import { useStyles } from 'src/routes/safe/components/Balances/SendModal/screens/ChooseTxType/style'
import ContractInteractionIcon from 'src/routes/safe/components/Transactions/TxList/assets/custom.svg'
import { EthHashInfo } from '@gnosis.pm/safe-react-components'
import Collectible from '../assets/collectibles.svg'
import Token from '../assets/token.svg'
import { FEATURES } from 'src/config/networks/network.d'
import { getExplorerInfo } from 'src/config'
type ActiveScreen = 'sendFunds' | 'sendCollectible' | 'contractInteraction'
interface ChooseTxTypeProps {
onClose: () => void
recipientAddress?: string
recipientName?: string
setActiveScreen: React.Dispatch<React.SetStateAction<ActiveScreen>>
}
const ChooseTxType = ({ onClose, recipientAddress, setActiveScreen }: ChooseTxTypeProps): React.ReactElement => {
const ChooseTxType = ({
onClose,
recipientAddress,
recipientName,
setActiveScreen,
}: ChooseTxTypeProps): React.ReactElement => {
const classes = useStyles()
const featuresEnabled = useSelector(safeFeaturesEnabledSelector)
const erc721Enabled = featuresEnabled?.includes(FEATURES.ERC721)
@ -61,11 +70,18 @@ const ChooseTxType = ({ onClose, recipientAddress, setActiveScreen }: ChooseTxTy
</Row>
<Hairline />
{!!recipientAddress && (
<Row align="center">
<Row align="center" margin="md">
<Col className={classes.disclaimer} layout="column" middle="xs">
<Paragraph className={classes.disclaimerText} noMargin>
Please select what you will send to {recipientAddress}
Please select what you will send to
</Paragraph>
<EthHashInfo
hash={recipientAddress}
name={recipientName}
showAvatar
showCopyBtn
explorerUrl={getExplorerInfo(recipientAddress)}
/>
</Col>
</Row>
)}

View File

@ -19,13 +19,14 @@ export const useStyles = makeStyles(
},
disclaimerText: {
fontSize: md,
marginBottom: `${md}`,
},
closeIcon: {
height: '35px',
width: '35px',
},
buttonColumn: {
padding: '52px 0',
margin: '16px 0 44px 0',
'& > button': {
fontSize: md,
fontFamily: 'Averta',

View File

@ -1,21 +1,15 @@
import IconButton from '@material-ui/core/IconButton'
import { makeStyles } from '@material-ui/core/styles'
import Close from '@material-ui/icons/Close'
import OpenInNew from '@material-ui/icons/OpenInNew'
import classNames from 'classnames'
import React from 'react'
import { useDispatch, useSelector } from 'react-redux'
import { getExplorerInfo } from 'src/config'
import { EthHashInfo, Button } from '@gnosis.pm/safe-react-components'
import { styles } from './style'
import Identicon from 'src/components/Identicon'
import Modal from 'src/components/Modal'
import Block from 'src/components/layout/Block'
import Button from 'src/components/layout/Button'
import Col from 'src/components/layout/Col'
import Hairline from 'src/components/layout/Hairline'
import Link from 'src/components/layout/Link'
import Paragraph from 'src/components/layout/Paragraph'
import Row from 'src/components/layout/Row'
import {
@ -23,16 +17,11 @@ import {
safeNameSelector,
safeParamAddressFromStateSelector,
} from 'src/logic/safe/store/selectors'
import { md, secondary } from 'src/theme/variables'
import { WELCOME_ADDRESS } from 'src/routes/routes'
import { removeLocalSafe } from 'src/logic/safe/store/actions/removeLocalSafe'
import { sameAddress } from 'src/logic/wallets/ethAddresses'
import { saveDefaultSafe } from 'src/logic/safe/utils'
const openIconStyle = {
height: md,
color: secondary,
}
import { getExplorerInfo } from 'src/config'
const useStyles = makeStyles(styles)
@ -47,8 +36,6 @@ export const RemoveSafeModal = ({ isOpen, onClose }: RemoveSafeModalProps): Reac
const safeName = useSelector(safeNameSelector)
const defaultSafe = useSelector(defaultSafeSelector)
const dispatch = useDispatch()
const explorerInfo = getExplorerInfo(safeAddress)
const { url } = explorerInfo()
const onRemoveSafeHandler = async () => {
await dispatch(removeLocalSafe(safeAddress))
@ -82,28 +69,16 @@ export const RemoveSafeModal = ({ isOpen, onClose }: RemoveSafeModalProps): Reac
<Hairline />
<Block className={classes.container}>
<Row className={classes.owner}>
<Col align="center" xs={1}>
<Identicon address={safeAddress} diameter={32} />
</Col>
<Col xs={11}>
<Block className={classNames(classes.name, classes.userName)}>
<Paragraph noMargin size="lg" weight="bolder">
{safeName}
</Paragraph>
<Block className={classes.user} justify="center">
<Paragraph color="disabled" noMargin size="md">
{safeAddress}
</Paragraph>
<Link className={classes.open} target="_blank" to={url}>
<OpenInNew style={openIconStyle} />
</Link>
</Block>
</Block>
</Col>
<EthHashInfo
hash={safeAddress}
name={safeName}
showAvatar
showCopyBtn
explorerUrl={getExplorerInfo(safeAddress)}
/>
</Row>
<Hairline />
<Row className={classes.description}>
<Paragraph noMargin>
<Paragraph size="lg" noMargin>
Removing a Safe only removes it from your interface. <b>It does not delete the Safe</b>. You can always add
it back using the Safe&apos;s address.
</Paragraph>
@ -111,14 +86,15 @@ export const RemoveSafeModal = ({ isOpen, onClose }: RemoveSafeModalProps): Reac
</Block>
<Hairline />
<Row align="center" className={classes.buttonRow}>
<Button minHeight={42} minWidth={140} onClick={onClose}>
<Button size="md" onClick={onClose} color="secondary" variant="outlined">
Cancel
</Button>
<Button
className={classes.buttonRemove}
minWidth={140}
size="md"
onClick={onRemoveSafeHandler}
type="submit"
color="error"
variant="contained"
>
Remove

View File

@ -1,15 +1,16 @@
import { createStyles } from '@material-ui/core/styles'
import { background, error, lg, md, sm } from 'src/theme/variables'
import { error, lg, md, sm } from 'src/theme/variables'
export const styles = createStyles({
heading: {
boxSizing: 'border-box',
justifyContent: 'space-between',
maxHeight: '75px',
minHeight: '74px',
padding: `${sm} ${lg}`,
},
container: {
minHeight: '369px',
padding: `${sm}`,
},
manage: {
fontSize: lg,
@ -35,7 +36,6 @@ export const styles = createStyles({
whiteSpace: 'nowrap',
},
owner: {
backgroundColor: background,
padding: md,
alignItems: 'center',
},

View File

@ -2,8 +2,10 @@ import IconButton from '@material-ui/core/IconButton'
import MenuItem from '@material-ui/core/MenuItem'
import { makeStyles } from '@material-ui/core/styles'
import Close from '@material-ui/icons/Close'
import { Button } from '@gnosis.pm/safe-react-components'
import React, { ReactElement, useEffect, useState } from 'react'
import { useDispatch } from 'react-redux'
import styled from 'styled-components'
import { List } from 'immutable'
import Field from 'src/components/forms/Field'
@ -11,7 +13,6 @@ import GnoForm from 'src/components/forms/GnoForm'
import SelectField from 'src/components/forms/SelectField'
import { composeValidators, differentFrom, minValue, mustBeInteger, required } from 'src/components/forms/validator'
import Block from 'src/components/layout/Block'
import Button from 'src/components/layout/Button'
import Col from 'src/components/layout/Col'
import Hairline from 'src/components/layout/Hairline'
import Paragraph from 'src/components/layout/Paragraph'
@ -30,6 +31,14 @@ import { TxParameters } from 'src/routes/safe/container/hooks/useTransactionPara
const THRESHOLD_FIELD_NAME = 'threshold'
const StyledButton = styled(Button)`
&.Mui-disabled {
background-color: ${({ theme }) => theme.colors.primary};
color: ${({ theme }) => theme.colors.white};
opacity: 0.5;
}
`
const useStyles = makeStyles(styles)
type ChangeThresholdModalProps = {
@ -52,6 +61,7 @@ export const ChangeThresholdModal = ({
const [manualGasPrice, setManualGasPrice] = useState<string | undefined>()
const [manualGasLimit, setManualGasLimit] = useState<string | undefined>()
const [editedThreshold, setEditedThreshold] = useState<number>(threshold)
const [disabledSubmitForm, setDisabledSubmitForm] = useState<boolean>(true)
const {
gasCostFormatted,
@ -86,6 +96,12 @@ export const ChangeThresholdModal = ({
}
}, [safeAddress, editedThreshold])
const handleThreshold = ({ target }) => {
const value = parseInt(target.value)
setDisabledSubmitForm(value === editedThreshold || value === threshold)
setEditedThreshold(value)
}
const handleSubmit = async ({ txParameters }) => {
await dispatch(
createTransaction({
@ -154,9 +170,7 @@ export const ChangeThresholdModal = ({
<Field
data-testid="threshold-select-input"
name={THRESHOLD_FIELD_NAME}
onChange={({ target }) => {
setEditedThreshold(parseInt(target.value))
}}
onChange={handleThreshold}
render={(props) => (
<>
<SelectField {...props} disableError>
@ -166,11 +180,6 @@ export const ChangeThresholdModal = ({
</MenuItem>
))}
</SelectField>
{props.meta.error && props.meta.touched && (
<Paragraph className={classes.errorText} color="error" noMargin>
{props.meta.error}
</Paragraph>
)}
</>
)}
validate={composeValidators(required, mustBeInteger, minValue(1), differentFrom(threshold))}
@ -205,18 +214,18 @@ export const ChangeThresholdModal = ({
)}
<Row align="center" className={classes.buttonRow}>
<Button minWidth={140} onClick={onClose} color="secondary">
<Button size="md" onClick={onClose} variant="outlined" color="primary">
Cancel
</Button>
<Button
<StyledButton
color="primary"
minWidth={140}
size="md"
type="submit"
variant="contained"
disabled={txEstimationExecutionStatus === EstimationStatus.LOADING}
disabled={txEstimationExecutionStatus === EstimationStatus.LOADING || disabledSubmitForm}
>
Submit
</Button>
</StyledButton>
</Row>
</>
)}

View File

@ -33,7 +33,7 @@ const DetailsWithTxInfo = ({ children, txData, txInfo }: DetailsWithTxInfoProps)
let name
let avatarUrl
if (isCustomTxInfo(txInfo)) {
if (isCustomTxInfo(txInfo) && txInfo.toInfo) {
name = txInfo.toInfo.name
avatarUrl = txInfo.toInfo.logoUri
}