Fix more linting errors

This commit is contained in:
Moody Salem 2020-05-08 15:46:42 -04:00
parent 3b3f281319
commit 152e84bc25
No known key found for this signature in database
GPG Key ID: 8CB5CD10385138DB
18 changed files with 293 additions and 253 deletions

@ -24,6 +24,9 @@
],
"rules": {
"@typescript-eslint/explicit-function-return-type": "off",
"prettier/prettier": "error"
"prettier/prettier": "error",
"react/prop-types": "warn",
"@typescript-eslint/no-empty-function": "warn",
"react/display-name": "warn"
}
}

@ -15,7 +15,7 @@
/**
* @type {Cypress.PluginConfig}
*/
module.exports = (on, config) => {
module.exports = () => {
// `on` is used to hook into various events Cypress emits
// `config` is the resolved Cypress config
}

@ -70,7 +70,7 @@ const ButtonWrapper = styled.div<{ pending: boolean }>`
}
`
export default function Transaction({ hash, pending }) {
export default function Transaction({ hash, pending }: { hash: string; pending: boolean }) {
const { chainId } = useWeb3React()
const allTransactions = useAllTransactions()

@ -223,13 +223,21 @@ function renderTransactions(transactions, pending) {
)
}
interface AccountDetailsProps {
toggleWalletModal: () => void
pendingTransactions: any[]
confirmedTransactions: any[]
ENSName?: string
openOptions: () => void
}
export default function AccountDetails({
toggleWalletModal,
pendingTransactions,
confirmedTransactions,
ENSName,
openOptions
}) {
}: AccountDetailsProps) {
const { chainId, account, connector } = useWeb3React()
const theme = useContext(ThemeContext)

@ -63,7 +63,15 @@ const Input = styled.input<{ error: boolean }>`
// border-radius: 8px;
// `
export default function AddressInputPanel({ initialInput = '', onChange, onError }) {
export default function AddressInputPanel({
initialInput = '',
onChange,
onError
}: {
initialInput?: string
onChange: (val: { address: string; name?: string }) => void
onError: (error: boolean, input: string) => void
}) {
const { library } = useWeb3React()
const [input, setInput] = useState(initialInput ? initialInput : '')

@ -353,6 +353,17 @@ function ExchangePage({ sendingInput = false, history, params }: ExchangePagePro
const showInputApprove: boolean =
parsedAmounts[Field.INPUT] && inputApproval && JSBI.greaterThan(parsedAmounts[Field.INPUT].raw, inputApproval.raw)
// reset modal state when closed
function resetModal() {
// clear input if txn submitted
if (!pendingConfirmation) {
onUserInput(Field.INPUT, '')
}
setPendingConfirmation(true)
setAttemptingTxn(false)
setShowAdvanced(false)
}
// function for a pure send
async function onSend() {
setAttemptingTxn(true)
@ -644,17 +655,6 @@ function ExchangePage({ sendingInput = false, history, params }: ExchangePagePro
const warningHigh: boolean =
slippageFromTrade && parseFloat(slippageFromTrade.toFixed(4)) > ALLOWED_SLIPPAGE_HIGH / 100
// reset modal state when closed
function resetModal() {
// clear input if txn submitted
if (!pendingConfirmation) {
onUserInput(Field.INPUT, '')
}
setPendingConfirmation(true)
setAttemptingTxn(false)
setShowAdvanced(false)
}
function modalHeader() {
if (sending && !sendingWithSwap) {
return (

@ -133,7 +133,7 @@ const MigrateBanner = styled(AutoColumn)`
`};
`
function Header({ history }) {
export default function Header() {
const { account, chainId } = useWeb3React()
const userEthBalance = useAddressBalance(account, WETH[chainId])
@ -196,5 +196,3 @@ function Header({ history }) {
</HeaderFrame>
)
}
export default withRouter(Header)

@ -45,8 +45,20 @@ function escapeRegExp(string: string): string {
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') // $& means the whole matched string
}
export const Input = React.memo(({ value, onUserInput, placeHolder = null, ...rest }: any) => {
function enforcer(nextUserInput: string) {
export const Input = React.memo(function InnerInput({
value,
onUserInput,
placeHolder,
...rest
}: {
value: string | number
onUserInput: (string) => void
placeHolder?: string
align?: 'right' | 'left'
id?: string
onClick?: () => void
}) {
const enforcer = (nextUserInput: string) => {
if (nextUserInput === '' || inputRegex.test(escapeRegExp(nextUserInput))) {
onUserInput(nextUserInput)
}

@ -1,5 +1,5 @@
import React, { useState, useEffect } from 'react'
import { withRouter } from 'react-router-dom'
import { RouteComponentProps, withRouter } from 'react-router-dom'
import { TokenAmount, JSBI, Token, Pair } from '@uniswap/sdk'
import Row from '../Row'
@ -21,7 +21,7 @@ import { useWeb3React } from '@web3-react/core'
import { useAddressBalance } from '../../contexts/Balances'
import { usePair, useAllPairs } from '../../contexts/Pairs'
function PoolFinder({ history }) {
function PoolFinder({ history }: RouteComponentProps) {
const Fields = {
TOKEN0: 0,
TOKEN1: 1

@ -62,7 +62,7 @@ const Popup = styled.div`
`}
`
export default function QuestionHelper({ text }) {
export default function QuestionHelper({ text }: { text: string }) {
const [showPopup, setPopup] = useState(false)
return (

@ -153,22 +153,6 @@ export default function TransactionDetails({
const [deadlineInput, setDeadlineInput] = useState(deadline / 60)
function parseCustomDeadline(e) {
const val = e.target.value
const acceptableValues = [/^$/, /^\d+$/]
if (acceptableValues.some(re => re.test(val))) {
setDeadlineInput(val)
setDeadline(val * 60)
}
}
const setFromCustom = () => {
setActiveIndex(4)
inputRef.current.focus()
// if there's a value, evaluate the bounds
checkBounds(debouncedInput)
}
const updateSlippage = useCallback(
newSlippage => {
// round to 2 decimals to prevent ethers error
@ -180,6 +164,45 @@ export default function TransactionDetails({
[setRawSlippage]
)
const checkBounds = useCallback(
slippageValue => {
setWarningType(WARNING_TYPE.none)
if (slippageValue === '' || slippageValue === '.') {
return setWarningType(WARNING_TYPE.emptyInput)
}
// check bounds and set errors
if (Number(slippageValue) < 0 || Number(slippageValue) > 50) {
return setWarningType(WARNING_TYPE.invalidEntryBound)
}
if (Number(slippageValue) >= 0 && Number(slippageValue) < 0.1) {
setWarningType(WARNING_TYPE.riskyEntryLow)
}
if (Number(slippageValue) > 5) {
setWarningType(WARNING_TYPE.riskyEntryHigh)
}
//update the actual slippage value in parent
updateSlippage(Number(slippageValue))
},
[updateSlippage]
)
function parseCustomDeadline(e) {
const val = e.target.value
const acceptableValues = [/^$/, /^\d+$/]
if (acceptableValues.some(re => re.test(val))) {
setDeadlineInput(val)
setDeadline(val * 60)
}
}
const setFromCustom = () => {
setActiveIndex(4)
inputRef.current.focus()
// if there's a value, evaluate the bounds
checkBounds(debouncedInput)
}
// used for slippage presets
const setFromFixed = useCallback(
(index, slippage) => {
@ -213,30 +236,6 @@ export default function TransactionDetails({
}
}, [initialSlippage, setFromFixed])
const checkBounds = useCallback(
slippageValue => {
setWarningType(WARNING_TYPE.none)
if (slippageValue === '' || slippageValue === '.') {
return setWarningType(WARNING_TYPE.emptyInput)
}
// check bounds and set errors
if (Number(slippageValue) < 0 || Number(slippageValue) > 50) {
return setWarningType(WARNING_TYPE.invalidEntryBound)
}
if (Number(slippageValue) >= 0 && Number(slippageValue) < 0.1) {
setWarningType(WARNING_TYPE.riskyEntryLow)
}
if (Number(slippageValue) > 5) {
setWarningType(WARNING_TYPE.riskyEntryHigh)
}
//update the actual slippage value in parent
updateSlippage(Number(slippageValue))
},
[updateSlippage]
)
// check that the theyve entered number and correct decimal
const parseInput = e => {
const input = e.target.value

@ -1,13 +1,27 @@
import React, { createContext, useContext, useReducer, useMemo, useCallback, useEffect } from 'react'
import { Token, TokenAmount, WETH } from '@uniswap/sdk'
import { BigintIsh, Token, TokenAmount, WETH } from '@uniswap/sdk'
import { BigNumber } from 'ethers/utils'
import React, { createContext, useCallback, useContext, useEffect, useMemo, useReducer } from 'react'
import { useWeb3React } from '../hooks'
import { safeAccess, isAddress, getTokenAllowance } from '../utils'
import { getTokenAllowance, isAddress } from '../utils'
import { useBlockNumber } from './Application'
const UPDATE = 'UPDATE'
const AllowancesContext = createContext([])
interface AllowancesState {
[chainId: number]: {
[address: string]: {
[tokenAddress: string]: {
[spenderAddress: string]: {
value: BigintIsh
blockNumber: BigNumber
}
}
}
}
}
const AllowancesContext = createContext<[AllowancesState, any]>([{}, {}])
function useAllowancesContext() {
return useContext(AllowancesContext)
@ -20,11 +34,11 @@ function reducer(state, { type, payload }) {
return {
...state,
[networkId]: {
...(safeAccess(state, [networkId]) || {}),
...state?.[networkId],
[address]: {
...(safeAccess(state, [networkId, address]) || {}),
...state?.[networkId]?.[address],
[tokenAddress]: {
...(safeAccess(state, [networkId, address, tokenAddress]) || {}),
...state?.[networkId]?.[address]?.[tokenAddress],
[spenderAddress]: {
value,
blockNumber
@ -34,9 +48,8 @@ function reducer(state, { type, payload }) {
}
}
}
default: {
default:
throw Error(`Unexpected action type in AllowancesContext reducer: '${type}'.`)
}
}
}
@ -60,7 +73,7 @@ export function useAddressAllowance(address: string, token: Token, spenderAddres
const globalBlockNumber = useBlockNumber()
const [state, { update }] = useAllowancesContext()
const { value, blockNumber } = safeAccess(state, [chainId, address, token?.address, spenderAddress]) || {}
const { value, blockNumber } = state?.[chainId]?.[address]?.[token?.address]?.[spenderAddress] ?? {}
useEffect(() => {
if (
@ -92,6 +105,5 @@ export function useAddressAllowance(address: string, token: Token, spenderAddres
}
}, [address, token, spenderAddress, value, blockNumber, globalBlockNumber, chainId, library, update])
const newTokenAmount: TokenAmount = value ? new TokenAmount(token, value) : null
return newTokenAmount
return value ? new TokenAmount(token, value) : null
}

@ -1,7 +1,6 @@
import React, { createContext, useContext, useReducer, useMemo, useCallback, useEffect } from 'react'
import { useWeb3React } from '../hooks'
import { safeAccess } from '../utils'
const BLOCK_NUMBER = 'BLOCK_NUMBER'
const USD_PRICE = 'USD_PRICE'
@ -48,7 +47,7 @@ function reducer(state: ApplicationState, { type, payload }): ApplicationState {
return {
...state,
[BLOCK_NUMBER]: {
...(safeAccess(state, [BLOCK_NUMBER]) || {}),
...state?.[BLOCK_NUMBER],
[networkId]: blockNumber
}
}
@ -163,7 +162,7 @@ export function useBlockNumber() {
const [state] = useApplicationContext()
return safeAccess(state, [BLOCK_NUMBER, chainId])
return state?.[BLOCK_NUMBER]?.[chainId]
}
export function useWalletModalOpen() {

@ -3,20 +3,26 @@ import React, { createContext, useContext, useReducer, useMemo, useCallback, use
import TxnPopup from '../components/TxnPopup'
import { useWeb3React } from '../hooks'
import { safeAccess } from '../utils'
import { useBlockNumber, usePopups } from './Application'
const RESPONSE = 'response'
const CUSTOM_DATA = 'CUSTOM_DATA'
const BLOCK_NUMBER_CHECKED = 'BLOCK_NUMBER_CHECKED'
const RECEIPT = 'receipt'
const SUMMARY = 'summary'
const ADD = 'ADD'
const CHECK = 'CHECK'
const FINALIZE = 'FINALIZE'
interface TransactionState {}
interface TransactionState {
[chainId: number]: {
[txHash: string]: {
response: {
customData?: any
summary: any
}
receipt: any
}
}
}
const TransactionsContext = createContext<[TransactionState, { [updater: string]: (...args: any[]) => void }]>([{}, {}])
@ -24,21 +30,21 @@ export function useTransactionsContext() {
return useContext(TransactionsContext)
}
function reducer(state, { type, payload }) {
function reducer(state: TransactionState, { type, payload }): TransactionState {
switch (type) {
case ADD: {
const { networkId, hash, response } = payload
if (safeAccess(state, [networkId, hash]) !== null) {
if (state[networkId]?.[hash]) {
throw Error('Attempted to add existing transaction.')
}
return {
...state,
[networkId]: {
...(safeAccess(state, [networkId]) || {}),
...state[networkId],
[hash]: {
[RESPONSE]: response
response
}
}
}
@ -46,16 +52,16 @@ function reducer(state, { type, payload }) {
case CHECK: {
const { networkId, hash, blockNumber } = payload
if (safeAccess(state, [networkId, hash]) === null) {
if (!state[networkId]?.[hash]) {
throw Error('Attempted to check non-existent transaction.')
}
return {
...state,
[networkId]: {
...(safeAccess(state, [networkId]) || {}),
...state[networkId],
[hash]: {
...(safeAccess(state, [networkId, hash]) || {}),
...state[networkId]?.[hash],
[BLOCK_NUMBER_CHECKED]: blockNumber
}
}
@ -64,17 +70,17 @@ function reducer(state, { type, payload }) {
case FINALIZE: {
const { networkId, hash, receipt } = payload
if (safeAccess(state, [networkId, hash]) === null) {
if (!state[networkId]?.[hash]) {
throw Error('Attempted to finalize non-existent transaction.')
}
return {
...state,
[networkId]: {
...(safeAccess(state, [networkId]) || {}),
...state[networkId],
[hash]: {
...(safeAccess(state, [networkId, hash]) || {}),
[RECEIPT]: receipt
...state[networkId]?.[hash],
receipt
}
}
}
@ -113,7 +119,7 @@ export function Updater() {
const globalBlockNumber = useBlockNumber()
const [state, { check, finalize }] = useTransactionsContext()
const allTransactions = safeAccess(state, [chainId]) || {}
const allTransactions = state[chainId] ?? {}
// show popup on confirm
const [, addPopup] = usePopups()
@ -123,7 +129,7 @@ export function Updater() {
let stale = false
Object.keys(allTransactions)
.filter(
hash => !allTransactions[hash][RECEIPT] && allTransactions[hash][BLOCK_NUMBER_CHECKED] !== globalBlockNumber
hash => !allTransactions[hash].receipt && allTransactions[hash][BLOCK_NUMBER_CHECKED] !== globalBlockNumber
)
.forEach(hash => {
library
@ -181,11 +187,11 @@ export function useTransactionAdder() {
if (!(chainId || chainId === 0)) {
throw Error(`Invalid networkId '${chainId}`)
}
const hash = safeAccess(response, ['hash'])
const hash = response?.hash
if (!hash) {
throw Error('No transaction hash found.')
}
add(chainId, hash, { ...response, [CUSTOM_DATA]: customData, [SUMMARY]: summary })
add(chainId, hash, { ...response, customData: customData, [SUMMARY]: summary })
},
[chainId, add]
)
@ -196,18 +202,18 @@ export function useAllTransactions() {
const [state] = useTransactionsContext()
return safeAccess(state, [chainId]) || {}
return state[chainId] || {}
}
export function usePendingApproval(tokenAddress) {
const allTransactions = useAllTransactions()
return (
Object.keys(allTransactions).filter(hash => {
if (allTransactions[hash][RECEIPT]) {
if (allTransactions[hash]?.receipt) {
return false
} else if (!allTransactions[hash][RESPONSE]) {
} else if (!allTransactions[hash]?.response) {
return false
} else if (allTransactions[hash][RESPONSE][CUSTOM_DATA].approval !== tokenAddress) {
} else if (allTransactions[hash]?.response?.customData?.approval !== tokenAddress) {
return false
} else {
return true

@ -425,6 +425,13 @@ export default function RemoveLiquidity({ token0, token1 }) {
})
}
function resetModalState() {
setSigned(false)
setSigInputs(null)
setAttemptedRemoval(false)
setPendingConfirmation(true)
}
async function onRemove() {
setAttemptedRemoval(true)
const router = getRouterContract(chainId, library, account)
@ -499,13 +506,6 @@ export default function RemoveLiquidity({ token0, token1 }) {
})
}
function resetModalState() {
setSigned(false)
setSigInputs(null)
setAttemptedRemoval(false)
setPendingConfirmation(true)
}
function modalHeader() {
return (
<AutoColumn gap={'sm'} style={{ marginTop: '20px' }}>

@ -1,10 +1,14 @@
import React, { useEffect } from 'react'
import styled, { ThemeProvider as StyledComponentsThemeProvider, createGlobalStyle, css } from 'styled-components'
import styled, {
ThemeProvider as StyledComponentsThemeProvider,
createGlobalStyle,
css,
DefaultTheme
} from 'styled-components'
import { getQueryParam, checkSupportedTheme } from '../utils'
import { SUPPORTED_THEMES } from '../constants'
import { useDarkModeManager } from '../contexts/LocalStorage'
import { Text } from 'rebass'
import { UniswapTheme } from './styled'
export * from './components'
@ -30,6 +34,80 @@ const mediaWidthTemplates: { [width in keyof typeof MEDIA_WIDTHS]: typeof css }
const white = '#FFFFFF'
const black = '#000000'
export function theme(darkMode: boolean): DefaultTheme {
return {
// base
white,
black,
// text
text1: darkMode ? '#FFFFFF' : '#000000',
text2: darkMode ? '#CED0D9' : '#565A69',
text3: darkMode ? '#6C7284' : '#888D9B',
text4: darkMode ? '#565A69' : '#C3C5CB',
text5: '#EDEEF2',
// backgrounds / greys
bg1: darkMode ? '#212429' : '#FFFFFF',
bg2: darkMode ? '#2C2F36' : '#F7F8FA',
bg3: darkMode ? '#40444F' : '#EDEEF2',
bg4: darkMode ? '#565A69' : '#CED0D9',
bg5: darkMode ? '#565A69' : '#888D9B',
modalBG: darkMode ? 'rgba(0,0,0,0.85)' : 'rgba(0,0,0,0.6)',
advancedBG: darkMode ? 'rgba(0,0,0,0.15)' : 'rgba(255,255,255,0.6)',
//blues
blue1: darkMode ? '#2172E5' : '#ff007a',
blue2: darkMode ? '#3680E7' : '#1966D2',
blue3: darkMode ? '#4D8FEA' : '#165BBB',
// blue4: darkMode ? '#153d6f70' : '#C4D9F8',
// blue5: darkMode ? '#153d6f70' : '#EBF4FF',
blue4: darkMode ? '#153d6f70' : '#F6DDE8',
blue5: darkMode ? '#153d6f70' : '#FDEAF1',
buttonSecondaryText: darkMode ? '#6da8ff' : '#ff007a',
// blue1: '#ff007a',
// blue4: '#F6DDE8',
// blue5: '#FDEAF1',
// pinks
pink1: '#DC6BE5',
pink2: darkMode ? '#2172E5' : '#ff007a',
pink3: darkMode ? '#17000b26' : '#F6DDE8',
pink4: darkMode ? '#17000b26' : '#FDEAF1',
// other
red1: '#FF6871',
green1: '#27AE60',
yellow1: '#FFE270',
yellow2: '#F3841E',
grids: {
sm: 8,
md: 12,
lg: 24
},
//shadows
shadow1: darkMode ? '#000' : '#2F80ED',
// media queries
mediaWidth: mediaWidthTemplates,
// css snippets
flexColumnNoWrap: css`
display: flex;
flex-flow: column nowrap;
`,
flexRowNoWrap: css`
display: flex;
flex-flow: row nowrap;
`
}
}
export default function ThemeProvider({ children }) {
const [darkMode, toggleDarkMode] = useDarkModeManager()
const themeURL = checkSupportedTheme(getQueryParam(window.location, 'theme'))
@ -46,78 +124,6 @@ export default function ThemeProvider({ children }) {
return <StyledComponentsThemeProvider theme={theme(themeToRender)}>{children}</StyledComponentsThemeProvider>
}
export const theme: (darkMode: boolean) => UniswapTheme = darkMode => ({
// base
white,
black,
// text
text1: darkMode ? '#FFFFFF' : '#000000',
text2: darkMode ? '#CED0D9' : '#565A69',
text3: darkMode ? '#6C7284' : '#888D9B',
text4: darkMode ? '#565A69' : '#C3C5CB',
text5: '#EDEEF2',
// backgrounds / greys
bg1: darkMode ? '#212429' : '#FFFFFF',
bg2: darkMode ? '#2C2F36' : '#F7F8FA',
bg3: darkMode ? '#40444F' : '#EDEEF2',
bg4: darkMode ? '#565A69' : '#CED0D9',
bg5: darkMode ? '#565A69' : '#888D9B',
modalBG: darkMode ? 'rgba(0,0,0,0.85)' : 'rgba(0,0,0,0.6)',
advancedBG: darkMode ? 'rgba(0,0,0,0.15)' : 'rgba(255,255,255,0.6)',
//blues
blue1: darkMode ? '#2172E5' : '#ff007a',
blue2: darkMode ? '#3680E7' : '#1966D2',
blue3: darkMode ? '#4D8FEA' : '#165BBB',
// blue4: darkMode ? '#153d6f70' : '#C4D9F8',
// blue5: darkMode ? '#153d6f70' : '#EBF4FF',
blue4: darkMode ? '#153d6f70' : '#F6DDE8',
blue5: darkMode ? '#153d6f70' : '#FDEAF1',
buttonSecondaryText: darkMode ? '#6da8ff' : '#ff007a',
// blue1: '#ff007a',
// blue4: '#F6DDE8',
// blue5: '#FDEAF1',
// pinks
pink1: '#DC6BE5',
pink2: darkMode ? '#2172E5' : '#ff007a',
pink3: darkMode ? '#17000b26' : '#F6DDE8',
pink4: darkMode ? '#17000b26' : '#FDEAF1',
// other
red1: '#FF6871',
green1: '#27AE60',
yellow1: '#FFE270',
yellow2: '#F3841E',
grids: {
sm: 8,
md: 12,
lg: 24
},
//shadows
shadow1: darkMode ? '#000' : '#2F80ED',
// media queries
mediaWidth: mediaWidthTemplates,
// css snippets
flexColumnNoWrap: css`
display: flex;
flex-flow: column nowrap;
`,
flexRowNoWrap: css`
display: flex;
flex-flow: row nowrap;
`
})
const TextWrapper = styled(Text)`
color = ${({ color, theme }) => theme[color]}
`

118
src/theme/styled.d.ts vendored

@ -1,64 +1,62 @@
import { css, FlattenSimpleInterpolation } from 'styled-components'
export interface UniswapTheme {
// base
white: string
black: string
// text
text1: string
text2: string
text3: string
text4: string
text5: string
// backgrounds / greys
bg1: string
bg2: string
bg3: string
bg4: string
bg5: string
modalBG: string
advancedBG: string
//blues
blue1: string
blue2: string
blue3: string
blue4: string
blue5: string
buttonSecondaryText: string
// pinks
pink1: string
pink2: string
pink3: string
pink4: string
// other
red1: string
green1: string
yellow1: string
yellow2: string
grids: {
sm: number
md: number
lg: number
}
// shadows
shadow1: string
// media queries
mediaWidth: { [width in keyof typeof MEDIA_WIDTHS]: typeof css }
// css snippets
flexColumnNoWrap: FlattenSimpleInterpolation
flexRowNoWrap: FlattenSimpleInterpolation
}
declare module 'styled-components' {
export interface DefaultTheme extends UniswapTheme {}
export interface DefaultTheme {
// base
white: string
black: string
// text
text1: string
text2: string
text3: string
text4: string
text5: string
// backgrounds / greys
bg1: string
bg2: string
bg3: string
bg4: string
bg5: string
modalBG: string
advancedBG: string
//blues
blue1: string
blue2: string
blue3: string
blue4: string
blue5: string
buttonSecondaryText: string
// pinks
pink1: string
pink2: string
pink3: string
pink4: string
// other
red1: string
green1: string
yellow1: string
yellow2: string
grids: {
sm: number
md: number
lg: number
}
// shadows
shadow1: string
// media queries
mediaWidth: { [width in keyof typeof MEDIA_WIDTHS]: typeof css }
// css snippets
flexColumnNoWrap: FlattenSimpleInterpolation
flexRowNoWrap: FlattenSimpleInterpolation
}
}

@ -25,15 +25,6 @@ export enum ERROR_CODES {
TOKEN_DECIMALS = 2
}
export function safeAccess(object, path) {
return object
? path.reduce(
(accumulator, currentValue) => (accumulator && accumulator[currentValue] ? accumulator[currentValue] : null),
object
)
: null
}
const ETHERSCAN_PREFIXES = {
1: '',
3: 'ropsten.',