Merge branch 'development' into bugfix/safeList

This commit is contained in:
Fernando 2021-03-30 18:10:46 -03:00 committed by GitHub
commit 8e5b4104e3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
35 changed files with 209 additions and 173 deletions

View File

@ -36,8 +36,12 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Cancel Previous Runs
uses: styfle/cancel-workflow-action@0.8.0
with:
access_token: ${{ github.token }}
- name: Remove broken apt repos [Ubuntu]
if: matrix.os == 'ubuntu-latest'
if: ${{ matrix.os }} == 'ubuntu-latest'
run: |
for apt_file in `grep -lr microsoft /etc/apt/sources.list.d/`; do sudo rm $apt_file; done
- uses: actions/checkout@v2
@ -65,9 +69,9 @@ jobs:
yarn cache clean
# Set production flag
- name: Set production flag for tag build
- name: Set production flag for release PR or tagged build
run: echo "REACT_APP_ENV=production" >> $GITHUB_ENV
if: startsWith(github.ref, 'refs/tags/v')
if: startsWith(github.ref, 'refs/tags/v') || github.base_ref == 'master'
- name: Build ${{ env.REACT_APP_NETWORK }} app
run: yarn build
@ -101,7 +105,6 @@ jobs:
* [Safe Multisig app ${{ env.REACT_APP_NETWORK }}](${{ env.REVIEW_FEATURE_URL }}/${{ env.REACT_APP_NETWORK }}/app/)
repo-token: ${{ secrets.GITHUB_TOKEN }}
repo-token-user-login: 'github-actions[bot]'
allow-repeats: true
if: success() && github.event.number
env:
REVIEW_FEATURE_URL: https://pr${{ github.event.number }}--${{ env.REPO_NAME_ALPHANUMERIC }}.review.gnosisdev.com

View File

@ -35,8 +35,12 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Cancel Previous Runs
uses: styfle/cancel-workflow-action@0.8.0
with:
access_token: ${{ github.token }}
- name: Remove broken apt repos [Ubuntu]
if: matrix.os == 'ubuntu-latest'
if: ${{ matrix.os }} == 'ubuntu-latest'
run: |
for apt_file in `grep -lr microsoft /etc/apt/sources.list.d/`; do sudo rm $apt_file; done
- uses: actions/checkout@v2
@ -64,9 +68,9 @@ jobs:
yarn cache clean
# Set production flag
- name: Set production flag for tag build
- name: Set production flag for release PR or tagged build
run: echo "REACT_APP_ENV=production" >> $GITHUB_ENV
if: startsWith(github.ref, 'refs/tags/v')
if: startsWith(github.ref, 'refs/tags/v') || github.base_ref == 'master'
- name: Build ${{ env.REACT_APP_NETWORK }} app
run: yarn build
@ -103,7 +107,6 @@ jobs:
* [Safe Multisig app ${{ env.REACT_APP_NETWORK }}](${{ env.REVIEW_FEATURE_URL }}/${{ env.REACT_APP_NETWORK }}/app/)
repo-token: ${{ secrets.GITHUB_TOKEN }}
repo-token-user-login: 'github-actions[bot]'
allow-repeats: true
if: success() && github.event.number
env:
REVIEW_FEATURE_URL: https://pr${{ github.event.number }}--${{ env.REPO_NAME_ALPHANUMERIC }}.review.gnosisdev.com

View File

@ -37,6 +37,10 @@ jobs:
name: Deployment
runs-on: ubuntu-latest
steps:
- name: Cancel Previous Runs
uses: styfle/cancel-workflow-action@0.8.0
with:
access_token: ${{ github.token }}
- name: Remove broken apt repos [Ubuntu]
if: ${{ matrix.os }} == 'ubuntu-latest'
run: |
@ -66,9 +70,9 @@ jobs:
yarn cache clean
# Set production flag
- name: Set production flag for tag build
- name: Set production flag for release PR or tagged build
run: echo "REACT_APP_ENV=production" >> $GITHUB_ENV
if: startsWith(github.ref, 'refs/tags/v')
if: startsWith(github.ref, 'refs/tags/v') || github.base_ref == 'master'
- name: Build ${{ env.REACT_APP_NETWORK }} app ${{ env.REACT_APP_ENV }}
run: yarn build
@ -103,7 +107,6 @@ jobs:
* [Safe Multisig app ${{ env.REACT_APP_NETWORK }}](${{ env.REVIEW_FEATURE_URL }}/${{ env.REACT_APP_NETWORK }}/app/)
repo-token: ${{ secrets.GITHUB_TOKEN }}
repo-token-user-login: 'github-actions[bot]'
allow-repeats: true
if: success() && github.event.number
env:
REVIEW_FEATURE_URL: https://pr${{ github.event.number }}--${{ env.REPO_NAME_ALPHANUMERIC }}.review.gnosisdev.com

View File

@ -36,8 +36,12 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Cancel Previous Runs
uses: styfle/cancel-workflow-action@0.8.0
with:
access_token: ${{ github.token }}
- name: Remove broken apt repos [Ubuntu]
if: matrix.os == 'ubuntu-latest'
if: ${{ matrix.os }} == 'ubuntu-latest'
run: |
for apt_file in `grep -lr microsoft /etc/apt/sources.list.d/`; do sudo rm $apt_file; done
- uses: actions/checkout@v2
@ -65,9 +69,9 @@ jobs:
yarn cache clean
# Set production flag
- name: Set production flag for tag build
- name: Set production flag for release PR or tagged build
run: echo "REACT_APP_ENV=production" >> $GITHUB_ENV
if: startsWith(github.ref, 'refs/tags/v')
if: startsWith(github.ref, 'refs/tags/v') || github.base_ref == 'master'
- name: Build ${{ env.REACT_APP_NETWORK }} app
run: yarn build
@ -101,7 +105,6 @@ jobs:
* [Safe Multisig app ${{ env.REACT_APP_NETWORK }}](${{ env.REVIEW_FEATURE_URL }}/${{ env.REACT_APP_NETWORK }}/app/)
repo-token: ${{ secrets.GITHUB_TOKEN }}
repo-token-user-login: 'github-actions[bot]'
allow-repeats: true
if: success() && github.event.number
env:
REVIEW_FEATURE_URL: https://pr${{ github.event.number }}--${{ env.REPO_NAME_ALPHANUMERIC }}.review.gnosisdev.com

View File

@ -36,8 +36,12 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Cancel Previous Runs
uses: styfle/cancel-workflow-action@0.8.0
with:
access_token: ${{ github.token }}
- name: Remove broken apt repos [Ubuntu]
if: matrix.os == 'ubuntu-latest'
if: ${{ matrix.os }} == 'ubuntu-latest'
run: |
for apt_file in `grep -lr microsoft /etc/apt/sources.list.d/`; do sudo rm $apt_file; done
- uses: actions/checkout@v2
@ -65,9 +69,9 @@ jobs:
yarn cache clean
# Set production flag
- name: Set production flag for tag build
- name: Set production flag for release PR or tagged build
run: echo "REACT_APP_ENV=production" >> $GITHUB_ENV
if: startsWith(github.ref, 'refs/tags/v')
if: startsWith(github.ref, 'refs/tags/v') || github.base_ref == 'master'
- name: Build ${{ env.REACT_APP_NETWORK }} app
run: yarn build
@ -101,7 +105,6 @@ jobs:
* [Safe Multisig app ${{ env.REACT_APP_NETWORK }}](${{ env.REVIEW_FEATURE_URL }}/${{ env.REACT_APP_NETWORK }}/app/)
repo-token: ${{ secrets.GITHUB_TOKEN }}
repo-token-user-login: 'github-actions[bot]'
allow-repeats: true
if: success() && github.event.number
env:
REVIEW_FEATURE_URL: https://pr${{ github.event.number }}--${{ env.REPO_NAME_ALPHANUMERIC }}.review.gnosisdev.com

View File

@ -10,6 +10,10 @@ jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Cancel Previous Runs
uses: styfle/cancel-workflow-action@0.8.0
with:
access_token: ${{ github.token }}
- uses: actions/checkout@v2
- name: Setup Node.js
uses: actions/setup-node@v2

View File

@ -1,6 +1,6 @@
{
"name": "safe-react",
"version": "3.2.0",
"version": "3.3.0",
"description": "Allowing crypto users manage funds in a safer way",
"website": "https://github.com/gnosis/safe-react#readme",
"bugs": {
@ -161,7 +161,7 @@
"@gnosis.pm/safe-apps-sdk": "1.0.3",
"@gnosis.pm/safe-apps-sdk-v1": "npm:@gnosis.pm/safe-apps-sdk@0.4.2",
"@gnosis.pm/safe-contracts": "1.1.1-dev.2",
"@gnosis.pm/safe-react-components": "https://github.com/gnosis/safe-react-components.git#80f5db6",
"@gnosis.pm/safe-react-components": "https://github.com/gnosis/safe-react-components.git#a68a67e",
"@gnosis.pm/util-contracts": "2.0.6",
"@ledgerhq/hw-transport-node-hid-singleton": "5.45.0",
"@material-ui/core": "^4.11.0",

View File

@ -21,7 +21,7 @@ import { ETHEREUM_NETWORK } from 'src/config/networks/network.d'
import { networkSelector } from 'src/logic/wallets/store/selectors'
import { SAFELIST_ADDRESS, WELCOME_ADDRESS } from 'src/routes/routes'
import {
safeFiatBalancesTotalSelector,
safeTotalFiatBalanceSelector,
safeNameSelector,
safeParamAddressFromStateSelector,
} from 'src/logic/safe/store/selectors'
@ -79,7 +79,7 @@ const App: React.FC = ({ children }) => {
const safeAddress = useSelector(safeParamAddressFromStateSelector)
const safeName = useSelector(safeNameSelector) ?? ''
const { safeActionsState, onShow, onHide, showSendFunds, hideSendFunds } = useSafeActions()
const currentSafeBalance = useSelector(safeFiatBalancesTotalSelector)
const currentSafeBalance = useSelector(safeTotalFiatBalanceSelector)
const currentCurrency = useSelector(currentCurrencySelector)
const granted = useSelector(grantedSelector)
const sidebarItems = useSidebarItems()
@ -88,7 +88,7 @@ const App: React.FC = ({ children }) => {
useSafeScheduledUpdates(safeLoaded, safeAddress)
const sendFunds = safeActionsState.sendFunds
const formattedTotalBalance = currentSafeBalance ? formatAmountInUsFormat(currentSafeBalance) : ''
const formattedTotalBalance = currentSafeBalance ? formatAmountInUsFormat(currentSafeBalance.toString()) : ''
const balance =
!!formattedTotalBalance && !!currentCurrency ? `${formattedTotalBalance} ${currentCurrency}` : undefined

View File

@ -12,7 +12,7 @@ import Spacer from 'src/components/Spacer'
import Col from 'src/components/layout/Col'
import Img from 'src/components/layout/Img'
import Row from 'src/components/layout/Row'
import { border, headerHeight, md, screenSm, sm } from 'src/theme/variables'
import { headerHeight, md, screenSm, sm } from 'src/theme/variables'
import { useStateHandler } from 'src/logic/hooks/useStateHandler'
import SafeLogo from '../assets/gnosis-safe-multisig-logo.svg'
@ -29,8 +29,6 @@ const styles = () => ({
summary: {
alignItems: 'center',
backgroundColor: 'white',
borderBottom: `solid 2px ${border}`,
boxShadow: '0 2px 4px 0 rgba(212, 212, 211, 0.59)',
flexWrap: 'nowrap',
height: headerHeight,
position: 'fixed',

View File

@ -6,13 +6,11 @@ import ConnectButton from 'src/components/ConnectButton'
import Block from 'src/components/layout/Block'
import Paragraph from 'src/components/layout/Paragraph'
import Row from 'src/components/layout/Row'
import { lg, md } from 'src/theme/variables'
import { KeyRing } from 'src/components/AppLayout/Header/components/KeyRing'
import { Card } from '@gnosis.pm/safe-react-components'
import styled from 'styled-components'
const styles = () => ({
container: {
padding: `${md} 12px`,
},
logo: {
justifyContent: 'center',
},
@ -22,8 +20,8 @@ const styles = () => ({
textAlign: 'center',
},
connect: {
padding: `${md} ${lg}`,
textAlign: 'center',
marginTop: '60px',
},
connectText: {
letterSpacing: '1px',
@ -33,22 +31,24 @@ const styles = () => ({
},
})
const StyledCard = styled(Card)`
padding: 20px;
`
const ConnectDetails = ({ classes }) => (
<>
<div className={classes.container}>
<Row align="center" margin="lg">
<Paragraph className={classes.text} noMargin size="lg" weight="bolder">
Connect a Wallet
</Paragraph>
</Row>
</div>
<Row className={classes.logo} margin="lg">
<KeyRing center circleSize={75} dotRight={25} dotSize={25} dotTop={50} keySize={32} mode="error" />
<StyledCard>
<Row align="center" margin="lg">
<Paragraph className={classes.text} noMargin size="xl" weight="bolder">
Connect a Wallet
</Paragraph>
</Row>
<Row className={classes.logo}>
<KeyRing center circleSize={60} dotRight={20} dotSize={20} dotTop={50} keySize={28} mode="error" />
</Row>
<Block className={classes.connect}>
<ConnectButton data-testid="heading-connect-btn" />
</Block>
</>
</StyledCard>
)
export default withStyles(styles as any)(ConnectDetails)

View File

@ -2,7 +2,7 @@ import { makeStyles } from '@material-ui/core/styles'
import Dot from '@material-ui/icons/FiberManualRecord'
import classNames from 'classnames'
import * as React from 'react'
import { EthHashInfo, Identicon } from '@gnosis.pm/safe-react-components'
import { EthHashInfo, Identicon, Card } from '@gnosis.pm/safe-react-components'
import Spacer from 'src/components/Spacer'
import Block from 'src/components/layout/Block'
@ -18,6 +18,7 @@ import { getExplorerInfo } from 'src/config'
import { KeyRing } from 'src/components/AppLayout/Header/components/KeyRing'
import { CircleDot } from '../CircleDot'
import { createStyles } from '@material-ui/core'
import styled from 'styled-components'
import WalletIcon from '../../assets/wallet.svg'
@ -91,6 +92,9 @@ const styles = createStyles({
},
})
const StyledCard = styled(Card)`
padding: 0px;
`
type Props = {
connected: boolean
network: ETHEREUM_NETWORK
@ -116,11 +120,11 @@ export const UserDetails = ({
const classes = useStyles()
return (
<>
<StyledCard>
<Block className={classes.container}>
<Row align="center" className={classes.identicon} margin="md">
{connected ? (
<Identicon address={userAddress || 'random'} size="lg" />
<Identicon address={userAddress || 'random'} size="xxl" />
) : (
<KeyRing circleSize={75} dotRight={25} dotSize={25} dotTop={50} hideDot keySize={30} mode="warning" />
)}
@ -185,11 +189,11 @@ export const UserDetails = ({
variant="contained"
data-testid="disconnect-btn"
>
<Paragraph className={classes.disconnectText} color="white" noMargin size="md">
<Paragraph className={classes.disconnectText} color="white" noMargin size="lg">
Disconnect
</Paragraph>
</Button>
</Row>
</>
</StyledCard>
)
}

View File

@ -45,7 +45,7 @@ const IconContainer = styled.div`
`
const StyledButton = styled(Button)`
&&.MuiButton-root {
padding: 0 16px;
padding: 0 12px;
}
*:first-child {
margin: 0 4px 0 0;
@ -170,7 +170,7 @@ const SafeHeader = ({
<StyledText size="xl">{balance}</StyledText>
<StyledButton size="md" disabled={!granted} color="primary" variant="contained" onClick={onNewTransactionClick}>
<FixedIcon type="arrowSentWhite" />
<Text size="lg" color="white">
<Text size="xl" color="white">
New transaction
</Text>
</StyledButton>

View File

@ -17,16 +17,16 @@ const Container = styled.div`
`
const HeaderWrapper = styled.nav`
height: 54px;
height: 52px;
width: 100%;
z-index: 1;
z-index: 2;
background-color: white;
box-shadow: 0 0 4px 0 rgba(212, 212, 211, 0.59);
box-shadow: 0 2px 4px 0 rgba(40, 54, 61, 0.18);
`
const BodyWrapper = styled.div`
height: calc(100% - 54px);
height: calc(100% - 52px);
width: 100%;
display: flex;
flex-direction: row;
@ -41,7 +41,7 @@ const SidebarWrapper = styled.aside`
padding: 8px 8px 0 8px;
background-color: ${({ theme }) => theme.colors.white};
border-right: 2px solid ${({ theme }) => theme.colors.separator};
box-shadow: 0 2px 4px 0 rgba(40, 54, 61, 0.18);
`
const ContentWrapper = styled.section`

View File

@ -73,7 +73,7 @@ export const onConnectButtonClick = async () => {
}
const ConnectButton = (props): React.ReactElement => (
<Button color="primary" minWidth={140} onClick={onConnectButtonClick} variant="contained" {...props}>
<Button color="primary" minWidth={240} onClick={onConnectButtonClick} variant="contained" {...props}>
Connect
</Button>
)

View File

@ -21,7 +21,7 @@ const useStyles = makeStyles({
container: {
backgroundColor: '#fff',
bottom: '0',
boxShadow: '0 2px 4px 0 rgba(212, 212, 211, 0.59)',
boxShadow: '1px 2px 10px 0 rgba(40, 54, 61, 0.18)',
boxSizing: 'border-box',
display: 'flex',
justifyContent: 'center',

View File

@ -5,7 +5,7 @@ import { Text, EthHashInfo, CopyToClipboardBtn, IconText, FixedIcon } from '@gno
import get from 'lodash.get'
import { web3ReadOnly as web3 } from 'src/logic/wallets/getWeb3'
import { getExplorerInfo } from 'src/config'
import { getExplorerInfo, getNetworkInfo } from 'src/config'
import { DecodedData, DecodedDataBasicParameter, DecodedDataParameterValue } from 'src/types/transactions/decode.d'
import { DecodedTxDetail } from 'src/routes/safe/components/Apps/components/ConfirmTxModal'
@ -58,12 +58,14 @@ export const BasicTxInfo = ({
txData: string
txValue: string
}): ReactElement => {
const { nativeCoin } = getNetworkInfo()
return (
<BasicTxInfoWrapper>
{/* TO */}
<>
<Text size="lg" strong>
{`Send ${txValue} ETH to:`}
{`Send ${txValue} ${nativeCoin.symbol} to:`}
</Text>
<EthHashInfo
hash={txRecipient}

View File

@ -1,9 +1,11 @@
import axios from 'axios'
import { getSafeClientGatewayBaseUrl } from 'src/config'
import { getSafeClientGatewayBaseUrl, getNetworkInfo } 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
@ -33,5 +35,24 @@ export const fetchTokenCurrenciesBalances = async ({
checksumAddress(safeAddress),
)}/balances/${selectedCurrency}/?trusted=${trustedTokens}&exclude_spam=${excludeSpamTokens}`
return axios.get(url).then(({ data }) => data)
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
})
}

View File

@ -21,8 +21,8 @@ export const useLoadSafe = (safeAddress?: string): boolean => {
await dispatch(fetchSafe(safeAddress))
setIsSafeLoaded(true)
await dispatch(fetchSafeTokens(safeAddress))
dispatch(updateAvailableCurrencies())
dispatch(fetchTransactions(safeAddress))
await dispatch(updateAvailableCurrencies())
await dispatch(fetchTransactions(safeAddress))
dispatch(addViewedSafe(safeAddress))
}
}

View File

@ -3,7 +3,6 @@ import { batch, useDispatch } from 'react-redux'
import { fetchCollectibles } from 'src/logic/collectibles/store/actions/fetchCollectibles'
import { fetchSafeTokens } from 'src/logic/tokens/store/actions/fetchSafeTokens'
import { fetchEtherBalance } from 'src/logic/safe/store/actions/fetchEtherBalance'
import { checkAndUpdateSafe } from 'src/logic/safe/store/actions/fetchSafe'
import fetchTransactions from 'src/logic/safe/store/actions/transactions/fetchTransactions'
import { TIMEOUT } from 'src/utils/constants'
@ -17,9 +16,8 @@ export const useSafeScheduledUpdates = (safeLoaded: boolean, safeAddress?: strin
// has to run again
let mounted = true
const fetchSafeData = async (address: string): Promise<void> => {
await batch(async () => {
batch(async () => {
await Promise.all([
dispatch(fetchEtherBalance(address)),
dispatch(fetchSafeTokens(address)),
dispatch(fetchTransactions(address)),
dispatch(fetchCollectibles(address)),
@ -28,9 +26,7 @@ export const useSafeScheduledUpdates = (safeLoaded: boolean, safeAddress?: strin
})
if (mounted) {
timer.current = window.setTimeout(() => {
fetchSafeData(address)
}, TIMEOUT * 3)
timer.current = window.setTimeout(() => fetchSafeData(address), TIMEOUT * 3)
}
}

View File

@ -15,7 +15,7 @@ import { makeOwner } from 'src/logic/safe/store/models/owner'
import { checksumAddress } from 'src/utils/checksumAddress'
import { SafeOwner, SafeRecordProps } from 'src/logic/safe/store/models/safe'
import { AppReduxState } from 'src/store'
import { latestMasterContractVersionSelector } from 'src/logic/safe/store/selectors'
import { latestMasterContractVersionSelector, safeTotalFiatBalanceSelector } from 'src/logic/safe/store/selectors'
import { getSafeInfo } from 'src/logic/safe/utils/safeInformation'
import { getModules } from 'src/logic/safe/utils/modules'
import { getSpendingLimits } from 'src/logic/safe/utils/spendingLimits'
@ -46,6 +46,7 @@ export const buildSafe = async (
safeAdd: string,
safeName: string,
latestMasterContractVersion?: string,
totalFiatBalance?: number,
): Promise<SafeRecordProps> => {
const safeAddress = checksumAddress(safeAdd)
@ -80,7 +81,7 @@ export const buildSafe = async (
threshold,
owners,
ethBalance,
totalFiatBalance: 0,
totalFiatBalance: totalFiatBalance || 0,
nonce,
currentVersion: currentVersion ?? '',
needsUpdate,
@ -160,7 +161,8 @@ export default (safeAdd: string) => async (
const safeAddress = checksumAddress(safeAdd)
const safeName = (await getSafeName(safeAddress)) || 'LOADED SAFE'
const latestMasterContractVersion = latestMasterContractVersionSelector(getState())
const safeProps = await buildSafe(safeAddress, safeName, latestMasterContractVersion)
const totalFiatBalance = safeTotalFiatBalanceSelector(getState())
const safeProps = await buildSafe(safeAddress, safeName, latestMasterContractVersion, totalFiatBalance)
// `updateSafe`, as `loadSafesFromStorage` will populate the store previous to this call
// and `addSafe` will only add a newly non-existent safe

View File

@ -127,6 +127,6 @@ export const getActiveTokensAddressesForAllSafes = createSelector(safesListSelec
return addresses
})
export const safeFiatBalancesTotalSelector = createSelector(safeSelector, (currentSafe) => {
return currentSafe?.totalFiatBalance.toString()
export const safeTotalFiatBalanceSelector = createSelector(safeSelector, (currentSafe) => {
return currentSafe?.totalFiatBalance
})

View File

@ -13,6 +13,7 @@ import { safeActiveTokensSelector, safeSelector } from 'src/logic/safe/store/sel
import { tokensSelector } from 'src/logic/tokens/store/selectors'
import BigNumber from 'bignumber.js'
import { currentCurrencySelector } from 'src/logic/currencyValues/store/selectors'
import { ZERO_ADDRESS, sameAddress } from 'src/logic/wallets/ethAddresses'
export type BalanceRecord = {
tokenBalance: string
@ -38,6 +39,11 @@ const extractDataFromResult = (currentTokens: TokenState) => (
},
})
// Extract network token balance from backend balances
if (sameAddress(address, ZERO_ADDRESS)) {
acc.ethBalance = humanReadableValue(balance, Number(decimals))
}
if (currentTokens && !currentTokens.get(address)) {
acc.tokens = acc.tokens.push(makeToken({ ...tokenInfo }))
}

View File

@ -4,9 +4,10 @@ import { Icon, Link, Text } from '@gnosis.pm/safe-react-components'
import { makeStyles } from '@material-ui/core/styles'
import CheckCircle from '@material-ui/icons/CheckCircle'
import * as React from 'react'
import { styles } from './style'
import styled from 'styled-components'
import { styles } from './style'
import { padOwnerIndex } from 'src/routes/open/utils/padOwnerIndex'
import QRIcon from 'src/assets/icons/qrcode.svg'
import trash from 'src/assets/icons/trash.svg'
import { ScanQRModal } from 'src/components/ScanQRModal'
@ -88,7 +89,7 @@ export const calculateValuesAfterRemoving = (index: number, values: Record<strin
return newValues
}
const ownerToRemove = new RegExp(`owner${index}(Name|Address)`)
const ownerToRemove = new RegExp(`owner${padOwnerIndex(index)}(Name|Address)`)
if (ownerToRemove.test(key)) {
// skip, doing anything with the removed field
@ -101,7 +102,7 @@ export const calculateValuesAfterRemoving = (index: number, values: Record<strin
if (Number(ownerOrder) > index) {
// reduce by one the order of the owner
newValues[`owner${Number(ownerOrder) - 1}${ownerField}`] = values[key]
newValues[`owner${padOwnerIndex(Number(ownerOrder) - 1)}${ownerField}`] = values[key]
} else {
// previous owners to the deleted row
newValues[key] = values[key]

View File

@ -5,10 +5,10 @@ describe('calculateValuesAfterRemoving', () => {
// Given
const formContent = {
name: 'My Safe',
owner0Name: 'Owner 0',
owner0Address: '0x90F8bf6A479f320ead074411a4B0e7944Ea8c9C1',
owner1Name: 'Owner 1',
owner1Address: '0xFFcf8FDEE72ac11b5c542428B35EEF5769C409f0',
owner0000Name: 'Owner 0',
owner0000Address: '0x90F8bf6A479f320ead074411a4B0e7944Ea8c9C1',
owner0001Name: 'Owner 1',
owner0001Address: '0xFFcf8FDEE72ac11b5c542428B35EEF5769C409f0',
}
// When
@ -17,8 +17,8 @@ describe('calculateValuesAfterRemoving', () => {
// Then
expect(newFormContent).toStrictEqual({
name: 'My Safe',
owner0Name: 'Owner 0',
owner0Address: '0x90F8bf6A479f320ead074411a4B0e7944Ea8c9C1',
owner0000Name: 'Owner 0',
owner0000Address: '0x90F8bf6A479f320ead074411a4B0e7944Ea8c9C1',
})
})
@ -26,12 +26,12 @@ describe('calculateValuesAfterRemoving', () => {
// Given
const formContent = {
name: 'My Safe',
owner0Name: 'Owner 0',
owner0Address: '0x90F8bf6A479f320ead074411a4B0e7944Ea8c9C1',
owner1Name: 'Owner 1',
owner1Address: '0xFFcf8FDEE72ac11b5c542428B35EEF5769C409f0',
owner2Name: 'Owner 2',
owner2Address: '0x22d491Bde2303f2f43325b2108D26f1eAbA1e32b',
owner0000Name: 'Owner 0',
owner0000Address: '0x90F8bf6A479f320ead074411a4B0e7944Ea8c9C1',
owner0001Name: 'Owner 1',
owner0001Address: '0xFFcf8FDEE72ac11b5c542428B35EEF5769C409f0',
owner0002Name: 'Owner 2',
owner0002Address: '0x22d491Bde2303f2f43325b2108D26f1eAbA1e32b',
}
// When
@ -40,10 +40,10 @@ describe('calculateValuesAfterRemoving', () => {
// Then
expect(newFormContent).toStrictEqual({
name: 'My Safe',
owner0Name: 'Owner 0',
owner0Address: '0x90F8bf6A479f320ead074411a4B0e7944Ea8c9C1',
owner1Name: 'Owner 2',
owner1Address: '0x22d491Bde2303f2f43325b2108D26f1eAbA1e32b',
owner0000Name: 'Owner 0',
owner0000Address: '0x90F8bf6A479f320ead074411a4B0e7944Ea8c9C1',
owner0001Name: 'Owner 2',
owner0001Address: '0x22d491Bde2303f2f43325b2108D26f1eAbA1e32b',
})
})
})

View File

@ -1,4 +1,5 @@
import { LoadFormValues } from 'src/routes/load/container/Load'
import { padOwnerIndex } from 'src/routes/open/utils/padOwnerIndex'
import { CreateSafeValues } from 'src/routes/open/utils/safeDataExtractor'
export const FIELD_NAME = 'name'
@ -7,8 +8,8 @@ export const FIELD_OWNERS = 'owners'
export const FIELD_SAFE_NAME = 'safeName'
export const FIELD_CREATION_PROXY_SALT = 'safeCreationSalt'
export const getOwnerNameBy = (index: number): string => `owner${index.toString().padStart(4, '0')}Name`
export const getOwnerAddressBy = (index: number): string => `owner${index.toString().padStart(4, '0')}Address`
export const getOwnerNameBy = (index: number): string => `owner${padOwnerIndex(index)}Name`
export const getOwnerAddressBy = (index: number): string => `owner${padOwnerIndex(index)}Address`
export const getNumOwnersFrom = (values: CreateSafeValues | LoadFormValues): number => {
const accounts = Object.keys(values)

View File

@ -0,0 +1,3 @@
export const padOwnerIndex = (index: number | string): string => {
return index.toString().padStart(4, '0')
}

View File

@ -11,7 +11,6 @@ import { styles } from './style'
import Table from 'src/components/Table'
import { cellWidth } from 'src/components/Table/TableHead'
import Block from 'src/components/layout/Block'
import Button from 'src/components/layout/Button'
import ButtonLink from 'src/components/layout/ButtonLink'
import Col from 'src/components/layout/Col'
import Img from 'src/components/layout/Img'
@ -40,7 +39,19 @@ import { addressBookQueryParamsSelector, safesListSelector } from 'src/logic/saf
import { checksumAddress } from 'src/utils/checksumAddress'
import { grantedSelector } from 'src/routes/safe/container/selector'
import { useAnalytics, SAFE_NAVIGATION_EVENT } from 'src/utils/googleAnalytics'
import { FixedIcon, Text, Button } from '@gnosis.pm/safe-react-components'
import styled from 'styled-components'
const StyledButton = styled(Button)`
&&.MuiButton-root {
margin: 4px 12px 4px 0px;
padding: 0 12px;
min-width: auto;
}
svg {
margin: 0 6px 0 0;
}
`
const useStyles = makeStyles(styles)
interface AddressBookSelectedEntry extends AddressBookEntry {
@ -202,19 +213,21 @@ const AddressBookTable = (): ReactElement => {
testId={REMOVE_ENTRY_BUTTON}
/>
{granted ? (
<Button
className={classes.send}
<StyledButton
color="primary"
onClick={() => {
setSelectedEntry({ entry: row })
setSendFundsModalOpen(true)
}}
size="small"
testId={SEND_ENTRY_BUTTON}
size="md"
variant="contained"
data-testid={SEND_ENTRY_BUTTON}
>
Send
</Button>
<FixedIcon type="arrowSentWhite" />
<Text size="xl" color="white">
Send
</Text>
</StyledButton>
) : null}
</Row>
</TableCell>

View File

@ -1,4 +1,4 @@
import { lg, marginButtonImg, md, sm } from 'src/theme/variables'
import { lg, md, sm } from 'src/theme/variables'
import { createStyles } from '@material-ui/core'
export const styles = createStyles({
@ -37,7 +37,7 @@ export const styles = createStyles({
},
editEntryButton: {
cursor: 'pointer',
marginBottom: marginButtonImg,
marginBottom: '16px',
},
editEntryButtonNonOwner: {
cursor: 'pointer',
@ -45,13 +45,13 @@ export const styles = createStyles({
removeEntryButton: {
marginLeft: lg,
marginRight: lg,
marginBottom: marginButtonImg,
marginBottom: '16px',
cursor: 'pointer',
},
removeEntryButtonDisabled: {
marginLeft: lg,
marginRight: lg,
marginBottom: marginButtonImg,
marginBottom: '16px',
cursor: 'default',
},
removeEntryButtonNonOwner: {
@ -65,14 +65,6 @@ export const styles = createStyles({
boxSizing: 'border-box',
justifyContent: 'flex-end',
},
send: {
width: '75px',
minWidth: '75px',
borderRadius: '4px',
'& > span': {
fontSize: '14px',
},
},
leftIcon: {
marginRight: sm,
},

View File

@ -133,7 +133,7 @@ export const staticAppsList: Array<StaticAppInfo> = [
},
// Wallet-Connect
{
url: `${process.env.REACT_APP_IPFS_GATEWAY}/QmU1pT35yPXxpnABcH3pZ1MxFeyYVtftT5RKhWopQmZHQV`,
url: `${process.env.REACT_APP_IPFS_GATEWAY}/QmX9B982ZAaBzbm6yBoZUS3uLgcizYA6wW65RCXVRZkG6f`,
disabled: false,
networks: [
ETHEREUM_NETWORK.MAINNET,

View File

@ -1,4 +1,5 @@
import React, { useEffect, useMemo } from 'react'
import styled from 'styled-components'
import { useSelector } from 'react-redux'
import { List } from 'immutable'
import TableCell from '@material-ui/core/TableCell'
@ -8,11 +9,11 @@ import TableRow from '@material-ui/core/TableRow'
import { Skeleton } from '@material-ui/lab'
import InfoIcon from 'src/assets/icons/info_red.svg'
import { FixedIcon, Text, Button } from '@gnosis.pm/safe-react-components'
import Img from 'src/components/layout/Img'
import Table from 'src/components/Table'
import { cellWidth } from 'src/components/Table/TableHead'
import Button from 'src/components/layout/Button'
import Row from 'src/components/layout/Row'
import { BALANCE_ROW_TEST_ID } from 'src/routes/safe/components/Balances'
import AssetTableCell from 'src/routes/safe/components/Balances/AssetTableCell'
@ -30,6 +31,17 @@ import { makeStyles } from '@material-ui/core/styles'
import { styles } from './styles'
import { currentCurrencySelector } from 'src/logic/currencyValues/store/selectors'
const StyledButton = styled(Button)`
&&.MuiButton-root {
margin: 4px 12px 4px 0px;
padding: 0 12px;
min-width: auto;
}
svg {
margin: 0 6px 0 0;
}
`
const useStyles = makeStyles(styles)
type Props = {
@ -137,31 +149,25 @@ const Coins = (props: Props): React.ReactElement => {
<TableCell component="td">
<Row align="end" className={classes.actions}>
{granted && (
<Button
className={classes.send}
<StyledButton
color="primary"
onClick={() => showSendFunds(row.asset.address)}
size="small"
testId="balance-send-btn"
size="md"
variant="contained"
data-testid="balance-send-btn"
>
{/* <CallMade alt="Send Transaction" className={classNames(classes.leftIcon, classes.iconSmall)} /> */}
Send
</Button>
<FixedIcon type="arrowSentWhite" />
<Text size="xl" color="white">
Send
</Text>
</StyledButton>
)}
<Button
className={classes.receive}
color="primary"
onClick={showReceiveFunds}
size="small"
variant="contained"
>
{/* <CallReceived
alt="Receive Transaction"
className={classNames(classes.leftIcon, classes.iconSmall)}
/> */}
Receive
</Button>
<StyledButton color="primary" onClick={showReceiveFunds} size="md" variant="contained">
<FixedIcon type="arrowReceivedWhite" />
<Text size="xl" color="white">
Receive
</Text>
</StyledButton>
</Row>
</TableCell>
</TableRow>

View File

@ -1,4 +1,4 @@
import { sm, xs } from 'src/theme/variables'
import { sm } from 'src/theme/variables'
import { createStyles } from '@material-ui/core'
export const styles = createStyles({
@ -25,23 +25,6 @@ export const styles = createStyles({
justifyContent: 'flex-end',
visibility: 'hidden',
},
receive: {
width: '95px',
minWidth: '95px',
marginLeft: sm,
borderRadius: xs,
'& > span': {
fontSize: '14px',
},
},
send: {
width: '75px',
minWidth: '75px',
borderRadius: xs,
'& > span': {
fontSize: '14px',
},
},
leftIcon: {
marginRight: sm,
},

View File

@ -1,4 +1,4 @@
import React from 'react'
import React, { ReactElement } from 'react'
import IconButton from '@material-ui/core/IconButton'
import Close from '@material-ui/icons/Close'
import { makeStyles } from '@material-ui/core/styles'
@ -13,10 +13,9 @@ import Row from 'src/components/layout/Row'
import { styles } from './style'
import GnoForm from 'src/components/forms/GnoForm'
import { TxParameters } from 'src/routes/safe/container/hooks/useTransactionParameters'
import { composeValidators, minValue } from 'src/components/forms/validator'
import { minValue } from 'src/components/forms/validator'
import { ParametersStatus, areSafeParamsEnabled, areEthereumParamsVisible, ethereumTxParametersTitle } from '../utils'
import { getNetworkInfo } from 'src/config'
const StyledDivider = styled(Divider)`
margin: 16px 0;
@ -59,8 +58,6 @@ const StyledTextMt = styled(Text)`
const useStyles = makeStyles(styles)
const { label } = getNetworkInfo()
interface Props {
txParameters: TxParameters
onClose: (txParameters?: TxParameters) => void
@ -79,15 +76,7 @@ const formValidation = (values) => {
const safeNonceValidation = minValue(0, true)(safeNonce)
const safeTxGasValidation = composeValidators(minValue(0, true), (value: string) => {
if (!value) {
return
}
if (Number(value) > Number(ethGasLimit)) {
return `Bigger than ${label} gas limit.`
}
})(safeTxGas)
const safeTxGasValidation = minValue(0, true)(safeTxGas)
return {
ethGasLimit: ethGasLimitValidation,
@ -103,7 +92,7 @@ export const EditTxParametersForm = ({
txParameters,
parametersStatus = 'ENABLED',
isExecution,
}: Props): React.ReactElement => {
}: Props): ReactElement => {
const classes = useStyles()
const { safeNonce, safeTxGas, ethNonce, ethGasLimit, ethGasPrice } = txParameters

View File

@ -5,7 +5,7 @@ const disabled = '#5D6D74'
const errorColor = '#f02525'
const fancyColor = '#f02525'
const fontColor = '#001428'
const headerHeight = '53px'
const headerHeight = '52px'
const lg = '24px'
const marginButtonImg = '12px'
const md = '16px'

View File

@ -13,7 +13,7 @@ $warning: #ffc05f;
$fancy: #f02525;
$secondary: #008C73;
$headerHeight: 53px;
$headerHeight: 52px;
$marginButtonImg: 12px;
$lg: 24px;

View File

@ -1596,9 +1596,9 @@
solc "0.5.14"
truffle "^5.1.21"
"@gnosis.pm/safe-react-components@https://github.com/gnosis/safe-react-components.git#80f5db6":
"@gnosis.pm/safe-react-components@https://github.com/gnosis/safe-react-components.git#a68a67e":
version "0.5.0"
resolved "https://github.com/gnosis/safe-react-components.git#80f5db672d417ea410d58c8d713e46e16e3c7e7f"
resolved "https://github.com/gnosis/safe-react-components.git#a68a67e634d0be091856ebba9f6874eebb767cd7"
dependencies:
classnames "^2.2.6"
react-media "^1.10.0"