Commit 655b7956 authored by ianlapham's avatar ianlapham

basic send added

parent 4e2c5c1e
<svg width="21" height="21" viewBox="0 0 21 21" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M7.5 1.5H1.5V7.5H7.5V1.5ZM1.5 0H0V1.5V7.5V9H1.5H7.5H9V7.5V1.5V0H7.5H1.5ZM4.5 3H3V4.5V6H4.5H6V4.5V3H4.5ZM1.5 19.5V13.5H7.5V19.5H1.5ZM0 12H1.5H7.5H9V13.5V19.5V21H7.5H1.5H0V19.5V13.5V12ZM4.5 15H3V16.5V18H4.5H6V16.5V15H4.5ZM13.5 1.5H19.5V7.5H13.5V1.5ZM12 0H13.5H19.5H21V1.5V7.5V9H19.5H13.5H12V7.5V1.5V0ZM16.5 3H15V4.5V6H16.5H18V4.5V3H16.5ZM16.5 12H12V21H13.5V16.5H15V18H21V12H19.5V13.5H16.5V12ZM18 19.5H16.5V21H18V19.5ZM19.5 19.5H21V21H19.5V19.5Z" fill="black"/>
</svg>
...@@ -89,6 +89,27 @@ export const ButtonEmpty = styled(Base)` ...@@ -89,6 +89,27 @@ export const ButtonEmpty = styled(Base)`
} }
` `
export const ButtonWhite = styled(Base)`
border: 1px solid #edeef2;
background-color: ${({ theme }) => theme.panelBackground};
};
color: black;
&:focus {
box-shadow: 0 0 0 1pt ${({ theme }) => darken(0.05, '#edeef2')};
}
&:hover {
box-shadow: 0 0 0 1pt ${({ theme }) => darken(0.1, '#edeef2')};
}
&:active {
box-shadow: 0 0 0 1pt ${({ theme }) => darken(0.1, '#edeef2')};
}
&:disabled {
opacity: 50%;
cursor: auto;
}
`
const ButtonConfirmedStyle = styled(Base)` const ButtonConfirmedStyle = styled(Base)`
background-color: ${({ theme }) => lighten(0.5, theme.connectedGreen)}; background-color: ${({ theme }) => lighten(0.5, theme.connectedGreen)};
border: 1px solid ${({ theme }) => theme.connectedGreen}; border: 1px solid ${({ theme }) => theme.connectedGreen};
...@@ -160,7 +181,7 @@ export function ButtonDropwdownLight({ disabled, children, ...rest }) { ...@@ -160,7 +181,7 @@ export function ButtonDropwdownLight({ disabled, children, ...rest }) {
export function ButtonRadio({ active, children, ...rest }) { export function ButtonRadio({ active, children, ...rest }) {
if (!active) { if (!active) {
return <ButtonEmpty {...rest}>{children}</ButtonEmpty> return <ButtonWhite {...rest}>{children}</ButtonWhite>
} else { } else {
return <ButtonPrimary {...rest}>{children}</ButtonPrimary> return <ButtonPrimary {...rest}>{children}</ButtonPrimary>
} }
......
...@@ -48,10 +48,9 @@ const InputRow = styled.div` ...@@ -48,10 +48,9 @@ const InputRow = styled.div`
const CurrencySelect = styled.button` const CurrencySelect = styled.button`
align-items: center; align-items: center;
height: 2.2rem; height: 2.2rem;
font-size: 20px; font-size: 20px;
background-color: ${({ selected, theme }) => (selected ? theme.buttonBackgroundPlain : theme.zumthorBlue)}; background-color: ${({ selected, theme }) => (selected ? theme.buttonBackgroundPlain : theme.royalBlue)};
color: ${({ selected, theme }) => (selected ? theme.textColor : theme.royalBlue)}; color: ${({ selected, theme }) => (selected ? theme.textColor : theme.white)};
border: 1px solid border: 1px solid
${({ selected, theme, disableTokenSelect }) => ${({ selected, theme, disableTokenSelect }) =>
disableTokenSelect ? theme.buttonBackgroundPlain : selected ? theme.buttonOutlinePlain : theme.royalBlue}; disableTokenSelect ? theme.buttonBackgroundPlain : selected ? theme.buttonOutlinePlain : theme.royalBlue};
...@@ -70,7 +69,8 @@ const CurrencySelect = styled.button` ...@@ -70,7 +69,8 @@ const CurrencySelect = styled.button`
} }
:active { :active {
background-color: ${({ theme }) => theme.zumthorBlue}; background-color: ${({ selected, theme }) =>
selected ? darken(0.1, theme.zumthorBlue) : darken(0.1, theme.royalBlue)};
} }
` `
...@@ -85,20 +85,20 @@ const StyledDropDown = styled(DropDown)` ...@@ -85,20 +85,20 @@ const StyledDropDown = styled(DropDown)`
height: 35%; height: 35%;
path { path {
stroke: ${({ selected, theme }) => (selected ? theme.textColor : theme.royalBlue)}; stroke: ${({ selected, theme }) => (selected ? theme.textColor : theme.white)};
} }
` `
const InputPanel = styled.div` const InputPanel = styled.div`
${({ theme }) => theme.flexColumnNoWrap} ${({ theme }) => theme.flexColumnNoWrap}
position: relative; position: relative;
border-radius: 1.25rem; border-radius: ${({ hideInput }) => (hideInput ? '8px' : '20px')};
background-color: ${({ theme }) => theme.inputBackground}; background-color: ${({ theme }) => theme.inputBackground};
z-index: 1; z-index: 1;
` `
const Container = styled.div` const Container = styled.div`
border-radius: 1.25rem; border-radius: ${({ hideInput }) => (hideInput ? '8px' : '20px')};
border: 1px solid ${({ error, theme }) => (error ? theme.salmonRed : theme.mercuryGray)}; border: 1px solid ${({ error, theme }) => (error ? theme.salmonRed : theme.mercuryGray)};
background-color: ${({ theme }) => theme.inputBackground}; background-color: ${({ theme }) => theme.inputBackground};
...@@ -174,7 +174,10 @@ export default function CurrencyInputPanel({ ...@@ -174,7 +174,10 @@ export default function CurrencyInputPanel({
hideBalance = false, hideBalance = false,
isExchange = false, isExchange = false,
exchange = null, // used for double token logo exchange = null, // used for double token logo
customBalance = null // used for LP balances instead of token balance customBalance = null, // used for LP balances instead of token balance
hideInput = false,
showSendWithSwap = false,
onTokenSelectSendWithSwap = null
}) { }) {
const { account, chainId } = useWeb3React() const { account, chainId } = useWeb3React()
const { t } = useTranslation() const { t } = useTranslation()
...@@ -236,7 +239,7 @@ export default function CurrencyInputPanel({ ...@@ -236,7 +239,7 @@ export default function CurrencyInputPanel({
return ( return (
<InputPanel> <InputPanel>
<Container error={!!error}> <Container error={!!error} hideInput={hideInput}>
{!hideBalance && ( {!hideBalance && (
<LabelRow> <LabelRow>
<RowBetween> <RowBetween>
...@@ -250,15 +253,19 @@ export default function CurrencyInputPanel({ ...@@ -250,15 +253,19 @@ export default function CurrencyInputPanel({
</RowBetween> </RowBetween>
</LabelRow> </LabelRow>
)} )}
<InputRow> <InputRow style={hideInput ? { padding: '0', borderRadius: '8px' } : {}} hideInput={hideInput}>
<NumericalInput {!hideInput && (
value={value} <>
onUserInput={val => { <NumericalInput
onUserInput(field, val) value={value}
}} onUserInput={val => {
/> onUserInput(field, val)
{!!token?.address && !atMax && <StyledBalanceMax onClick={onMax}>MAX</StyledBalanceMax>} }}
{renderUnlockButton()} />
{!!token?.address && !atMax && <StyledBalanceMax onClick={onMax}>MAX</StyledBalanceMax>}
{renderUnlockButton()}
</>
)}
<CurrencySelect <CurrencySelect
selected={!!token?.address} selected={!!token?.address}
onClick={() => { onClick={() => {
...@@ -296,6 +303,8 @@ export default function CurrencyInputPanel({ ...@@ -296,6 +303,8 @@ export default function CurrencyInputPanel({
urlAddedTokens={urlAddedTokens} urlAddedTokens={urlAddedTokens}
field={field} field={field}
onTokenSelect={onTokenSelection} onTokenSelect={onTokenSelection}
showSendWithSwap={showSendWithSwap}
onTokenSelectSendWithSwap={onTokenSelectSendWithSwap}
/> />
)} )}
</InputPanel> </InputPanel>
......
This diff is collapsed.
...@@ -5,11 +5,11 @@ const StyledInput = styled.input` ...@@ -5,11 +5,11 @@ const StyledInput = styled.input`
color: ${({ error, theme }) => error && theme.salmonRed}; color: ${({ error, theme }) => error && theme.salmonRed};
background-color: ${({ theme }) => theme.inputBackground}; background-color: ${({ theme }) => theme.inputBackground};
color: ${({ theme }) => theme.textColor}; color: ${({ theme }) => theme.textColor};
width: 0;
font-size: 20px; font-size: 20px;
outline: none; outline: none;
border: none; border: none;
flex: 1 1 auto; flex: 1 1 auto;
width: 0;
background-color: ${({ theme }) => theme.inputBackground}; background-color: ${({ theme }) => theme.inputBackground};
font-size: ${({ fontSize }) => fontSize && fontSize}; font-size: ${({ fontSize }) => fontSize && fontSize};
text-align: ${({ align }) => align && align}; text-align: ${({ align }) => align && align};
......
import React, { useState, useRef, useMemo, useEffect } from 'react' import React, { useState, useRef, useMemo, useEffect } from 'react'
import { withRouter } from 'react-router-dom' import '@reach/tooltip/styles.css'
import { Link } from 'react-router-dom'
import { Link as StyledLink } from '../../theme/components'
import { useTranslation } from 'react-i18next'
import { ethers } from 'ethers'
import styled from 'styled-components' import styled from 'styled-components'
import escapeStringRegex from 'escape-string-regexp' import escapeStringRegex from 'escape-string-regexp'
import '@reach/tooltip/styles.css' import { Link } from 'react-router-dom'
import { ethers } from 'ethers'
import { isMobile } from 'react-device-detect' import { isMobile } from 'react-device-detect'
import { withRouter } from 'react-router-dom'
import { JSBI } from '@uniswap/sdk'
import { Text } from 'rebass' import { Link as StyledLink } from '../../theme/components'
import Column, { AutoColumn } from '../Column'
import { RowBetween, RowFixed } from '../Row' import Modal from '../Modal'
import Circle from '../../assets/images/circle.svg'
import TokenLogo from '../TokenLogo' import TokenLogo from '../TokenLogo'
import { CloseIcon } from '../../theme/components'
import DoubleTokenLogo from '../DoubleLogo' import DoubleTokenLogo from '../DoubleLogo'
import { useWeb3React } from '../../hooks' import Column, { AutoColumn } from '../Column'
import { isAddress } from '../../utils' import { Text } from 'rebass'
import Modal from '../Modal'
import { useToken, useAllTokens, INITIAL_TOKENS_CONTEXT } from '../../contexts/Tokens'
import { Spinner } from '../../theme' import { Spinner } from '../../theme'
import Circle from '../../assets/images/circle.svg' import { CloseIcon } from '../../theme/components'
import { ColumnCenter } from '../../components/Column'
import { RowBetween, RowFixed } from '../Row'
import { isAddress } from '../../utils'
import { useWeb3React } from '../../hooks'
import { useAllBalances } from '../../contexts/Balances' import { useAllBalances } from '../../contexts/Balances'
import { useTranslation } from 'react-i18next'
import { useAllExchanges } from '../../contexts/Exchanges' import { useAllExchanges } from '../../contexts/Exchanges'
import { useToken, useAllTokens, INITIAL_TOKENS_CONTEXT } from '../../contexts/Tokens'
const TokenModalInfo = styled.div` const TokenModalInfo = styled.div`
${({ theme }) => theme.flexRowNoWrap} ${({ theme }) => theme.flexRowNoWrap}
...@@ -108,7 +112,17 @@ const MenuItem = styled(PaddedItem)` ...@@ -108,7 +112,17 @@ const MenuItem = styled(PaddedItem)`
background-color: ${({ theme }) => theme.tokenRowHover}; background-color: ${({ theme }) => theme.tokenRowHover};
} }
` `
function SearchModal({ history, isOpen, onDismiss, onTokenSelect, urlAddedTokens, filterType, hiddenToken }) { function SearchModal({
history,
isOpen,
onDismiss,
onTokenSelect,
urlAddedTokens,
filterType,
hiddenToken,
showSendWithSwap,
onTokenSelectSendWithSwap
}) {
const { t } = useTranslation() const { t } = useTranslation()
const { account, chainId } = useWeb3React() const { account, chainId } = useWeb3React()
...@@ -171,6 +185,7 @@ function SearchModal({ history, isOpen, onDismiss, onTokenSelect, urlAddedTokens ...@@ -171,6 +185,7 @@ function SearchModal({ history, isOpen, onDismiss, onTokenSelect, urlAddedTokens
let balance let balance
// only update if we have data // only update if we have data
balance = allBalances?.[account]?.[k] balance = allBalances?.[account]?.[k]
return { return {
name: allTokens[k].name, name: allTokens[k].name,
symbol: allTokens[k].symbol, symbol: allTokens[k].symbol,
...@@ -203,10 +218,16 @@ function SearchModal({ history, isOpen, onDismiss, onTokenSelect, urlAddedTokens ...@@ -203,10 +218,16 @@ function SearchModal({ history, isOpen, onDismiss, onTokenSelect, urlAddedTokens
}) })
}, [tokenList, searchQuery]) }, [tokenList, searchQuery])
function _onTokenSelect(address) { function _onTokenSelect(address, sendWithSwap = false) {
setSearchQuery('') if (sendWithSwap) {
onTokenSelect(address) setSearchQuery('')
onDismiss() onTokenSelectSendWithSwap(address)
onDismiss()
} else {
setSearchQuery('')
onTokenSelect(address)
onDismiss()
}
} }
// manage focus on modal show // manage focus on modal show
...@@ -340,8 +361,11 @@ function SearchModal({ history, isOpen, onDismiss, onTokenSelect, urlAddedTokens ...@@ -340,8 +361,11 @@ function SearchModal({ history, isOpen, onDismiss, onTokenSelect, urlAddedTokens
INITIAL_TOKENS_CONTEXT[chainId] && INITIAL_TOKENS_CONTEXT[chainId] &&
!INITIAL_TOKENS_CONTEXT[chainId].hasOwnProperty(address) && !INITIAL_TOKENS_CONTEXT[chainId].hasOwnProperty(address) &&
!urlAdded !urlAdded
const zeroBalance = JSBI.equal(JSBI.BigInt(0), balance.raw)
return ( return (
<MenuItem key={address} onClick={() => _onTokenSelect(address)}> <MenuItem key={address} onClick={() => (zeroBalance ? _onTokenSelect(address, true) : _onTokenSelect(address))}>
<RowFixed> <RowFixed>
<TokenLogo address={address} size={'24px'} style={{ marginRight: '14px' }} /> <TokenLogo address={address} size={'24px'} style={{ marginRight: '14px' }} />
<Column> <Column>
...@@ -353,7 +377,22 @@ function SearchModal({ history, isOpen, onDismiss, onTokenSelect, urlAddedTokens ...@@ -353,7 +377,22 @@ function SearchModal({ history, isOpen, onDismiss, onTokenSelect, urlAddedTokens
</RowFixed> </RowFixed>
<AutoColumn gap="4px" justify="end"> <AutoColumn gap="4px" justify="end">
{balance ? ( {balance ? (
<Text>{balance ? balance.toSignificant(6) : '-'}</Text> <Text>
{zeroBalance && showSendWithSwap ? (
<ColumnCenter
justify="center"
style={{ backgroundColor: '#EBF4FF', padding: '8px', borderRadius: '12px' }}
>
<Text textAlign="center" fontWeight={500} color="#2172E5">
Send With Swap
</Text>
</ColumnCenter>
) : balance ? (
balance.toSignificant(6)
) : (
'-'
)}
</Text>
) : account ? ( ) : account ? (
<SpinnerWrapper src={Circle} alt="loader" /> <SpinnerWrapper src={Circle} alt="loader" />
) : ( ) : (
......
...@@ -71,7 +71,7 @@ export default function InputSlider({ value, onChange }) { ...@@ -71,7 +71,7 @@ export default function InputSlider({ value, onChange }) {
value={typeof value === 'number' ? value : 0} value={typeof value === 'number' ? value : 0}
onChange={onChange} onChange={onChange}
aria-labelledby="input-slider" aria-labelledby="input-slider"
marks={marks} // marks={marks}
/> />
) )
} }
...@@ -52,7 +52,7 @@ export default function TokenLogo({ address, size = '24px', ...rest }) { ...@@ -52,7 +52,7 @@ export default function TokenLogo({ address, size = '24px', ...rest }) {
if (address === 'ETH') { if (address === 'ETH') {
return <StyledEthereumLogo size={size} {...rest} /> return <StyledEthereumLogo size={size} {...rest} />
} else if (!error && !BAD_IMAGES[address]) { } else if (!error && !BAD_IMAGES[address]) {
path = TOKEN_ICON_API(address.toLowerCase()) path = TOKEN_ICON_API(address?.toLowerCase())
} else { } else {
return ( return (
<Emoji {...rest} size={size}> <Emoji {...rest} size={size}>
......
import React from 'react'
import ExchangePage from '../../components/ExchangePage'
export default function Send({ initialCurrency, params }) {
return <ExchangePage initialCurrency={initialCurrency} params={params} sending={true} />
}
import React, { useState, useEffect } from 'react'
import styled from 'styled-components'
import { darken } from 'polished'
import { TokenAmount, JSBI } from '@uniswap/sdk'
import QR from '../../assets/svg/QR.svg'
import TokenLogo from '../../components/TokenLogo'
import SearchModal from '../../components/SearchModal'
import ExchangePage from '../../components/ExchangePage'
import NumericalInput from '../../components/NumericalInput'
import ConfirmationModal from '../../components/ConfirmationModal'
import { Text } from 'rebass'
import { TYPE } from '../../theme'
import { LightCard } from '../../components/Card'
import { ArrowDown } from 'react-feather'
import { AutoColumn } from '../../components/Column'
import { ButtonPrimary } from '../../components/Button'
import { ReactComponent as DropDown } from '../../assets/images/dropdown.svg'
import { useToken } from '../../contexts/Tokens'
import { RowBetween } from '../../components/Row'
import { useENSName } from '../../hooks'
import { useWeb3React } from '@web3-react/core'
import { useAddressBalance } from '../../contexts/Balances'
import { parseUnits } from '@ethersproject/units'
import { isAddress } from '../../utils'
const CurrencySelect = styled.button`
display: flex;
align-items: center;
justify-content: space-between;
font-size: 20px;
width: ${({ selected }) => (selected ? '128px' : '180px')}
padding: 8px 12px;
background-color: ${({ selected, theme }) => (selected ? theme.buttonBackgroundPlain : theme.royalBlue)};
color: ${({ selected, theme }) => (selected ? theme.textColor : theme.white)};
border: 1px solid
${({ selected, theme }) => (selected ? theme.outlineGrey : theme.royalBlue)};
border-radius: 8px;
outline: none;
cursor: pointer;
user-select: none;
:hover {
border: 1px solid
${({ selected, theme }) => (selected ? darken(0.1, theme.outlineGrey) : darken(0.1, theme.royalBlue))};
}
:focus {
border: 1px solid ${({ selected, theme }) =>
selected ? darken(0.1, theme.outlineGrey) : darken(0.1, theme.royalBlue)};
}
:active {
background-color: ${({ selected, theme }) => (selected ? theme.buttonBackgroundPlain : theme.royalBlue)};
}
`
const StyledDropDown = styled(DropDown)`
height: 35%;
path {
stroke: ${({ selected, theme }) => (selected ? theme.textColor : theme.white)};
}
`
const InputGroup = styled(AutoColumn)`
position: relative;
padding: 40px 0;
`
const QRWrapper = styled.div`
display: flex;
align-items: center;
justify-content: center;
border: 1px solid ${({ theme }) => theme.outlineGrey};
background: #fbfbfb;
padding: 4px;
border-radius: 8px;
`
const StyledInput = styled.input`
width: ${({ width }) => width};
border: none;
outline: none;
font-size: 20px;
::placeholder {
color: #edeef2;
}
`
const StyledNumerical = styled(NumericalInput)`
text-align: center;
font-size: 48px;
font-weight: 500px;
width: 100%;
::placeholder {
color: #edeef2;
}
`
const MaxButton = styled.button`
position: absolute;
right: 70px;
padding: 0.5rem 1rem;
background-color: ${({ theme }) => theme.zumthorBlue};
border: 1px solid ${({ theme }) => theme.zumthorBlue};
border-radius: 0.5rem;
font-size: 1rem;
font-weight: 500;
cursor: pointer;
margin-right: 0.5rem;
color: ${({ theme }) => theme.royalBlue};
:hover {
border: 1px solid ${({ theme }) => theme.royalBlue};
}
:focus {
border: 1px solid ${({ theme }) => theme.royalBlue};
outline: none;
}
`
export default function Send() {
const { account } = useWeb3React()
// setting for send with swap or regular swap
const [withSwap, setWithSwap] = useState(true)
// modals
const [modalOpen, setModalOpen] = useState(false)
const [showConfirm, setShowConfirm] = useState(false)
// token selected
const [activeTokenAddress, setActiveTokenAddress] = useState()
const token = useToken(activeTokenAddress)
// user inputs
const [typedValue, setTypedValue] = useState('')
const [amount, setAmount] = useState(null)
const [recipient, setRecipient] = useState('0x74Aa01d162E6dC6A657caC857418C403D48E2D77')
//ENS
const recipientENS = useENSName(recipient)
// balances
const userBalance = useAddressBalance(account, token)
//errors
const [generalError, setGeneralError] = useState('')
const [amountError, setAmountError] = useState('')
const [recipientError, setRecipientError] = useState('')
function parseInputAmount(newtypedValue) {
setTypedValue(newtypedValue)
if (!!token && newtypedValue !== '' && newtypedValue !== '.') {
const typedValueParsed = parseUnits(newtypedValue, token.decimals).toString()
setAmount(new TokenAmount(token, typedValueParsed))
}
}
function onMax() {
if (userBalance) {
setTypedValue(userBalance.toExact())
setAmount(userBalance)
}
}
const atMax = amount && userBalance && JSBI.equal(amount.raw, userBalance.raw) ? true : false
//error detection
useEffect(() => {
setGeneralError('')
setRecipientError('')
setAmountError('')
if (!amount) {
setGeneralError('Enter an amount')
}
if (!isAddress(recipient)) {
setRecipientError('Enter a valid address')
}
if (!!!token) {
setGeneralError('Select a token')
}
if (amount && userBalance && JSBI.greaterThan(amount.raw, userBalance.raw)) {
setAmountError('Insufficient Balance')
}
}, [recipient, token, amount, userBalance])
const TopContent = () => {
return (
<AutoColumn gap="30px" style={{ marginTop: '40px' }}>
<RowBetween>
<Text fontSize={36} fontWeight={500}>
{amount?.toFixed(8)}
</Text>
<TokenLogo address={activeTokenAddress} size={'30px'} />
</RowBetween>
<ArrowDown size={24} color="#888D9B" />
<TYPE.blue fontSize={36}>
{recipient?.slice(0, 6)}...{recipient?.slice(36, 42)}
</TYPE.blue>
</AutoColumn>
)
}
const BottomContent = () => {
return (
<AutoColumn>
<ButtonPrimary>
<Text color="white" fontSize={20}>
Confirm send
</Text>
</ButtonPrimary>
</AutoColumn>
)
}
const [attemptedSend, setAttemptedSend] = useState(false) // clicke confirm
const [pendingConfirmation, setPendingConfirmation] = useState(true) // waiting for
return withSwap ? (
<ExchangePage sendingInput={true} />
) : (
<>
<SearchModal
isOpen={modalOpen}
onDismiss={() => {
setModalOpen(false)
}}
filterType="tokens"
onTokenSelect={tokenAddress => setActiveTokenAddress(tokenAddress)}
/>
<ConfirmationModal
isOpen={showConfirm}
onDismiss={() => setShowConfirm(false)}
hash=""
title="Confirm Send"
topContent={TopContent}
bottomContent={BottomContent}
attemptingTxn={attemptedSend}
pendingConfirmation={pendingConfirmation}
pendingText=""
/>
</>
)
}
...@@ -41,7 +41,7 @@ const Wrapper = styled.div` ...@@ -41,7 +41,7 @@ const Wrapper = styled.div`
const FixedBottom = styled.div` const FixedBottom = styled.div`
position: absolute; position: absolute;
bottom: -240px; bottom: -200px;
width: 100%; width: 100%;
` `
......
...@@ -2,5 +2,5 @@ import React from 'react' ...@@ -2,5 +2,5 @@ import React from 'react'
import ExchangePage from '../../components/ExchangePage' import ExchangePage from '../../components/ExchangePage'
export default function Swap({ initialCurrency, params }) { export default function Swap({ initialCurrency, params }) {
return <ExchangePage initialCurrency={initialCurrency} params={params} /> return <ExchangePage sendingInput={false} />
} }
...@@ -128,6 +128,21 @@ export const TYPE = { ...@@ -128,6 +128,21 @@ export const TYPE = {
<Text fontWeight={500} color={theme().royalBlue} {...rest}> <Text fontWeight={500} color={theme().royalBlue} {...rest}>
{children} {children}
</Text> </Text>
),
gray: ({ children, ...rest }) => (
<Text fontWeight={500} color={theme().outlineGrey} {...rest}>
{children}
</Text>
),
italic: ({ children, ...rest }) => (
<Text fontWeight={500} fontSize={12} fontStyle={'italic'} color={theme().mineshaftGray} {...rest}>
{children}
</Text>
),
error: ({ children, error, ...rest }) => (
<Text fontWeight={500} color={error ? theme().salmonRed : theme().mineshaftGray} {...rest}>
{children}
</Text>
) )
} }
......
import { getMarketDetails } from '@uniswap/sdk'
import { getMedian, getMean } from './math'
const DAI = 'DAI'
const USDC = 'USDC'
const TUSD = 'TUSD'
const USD_STABLECOINS = [DAI, USDC, TUSD]
function forEachStablecoin(runner) {
return USD_STABLECOINS.map((stablecoin, index) => runner(index, stablecoin))
}
export function getUSDPrice(reserves) {
const marketDetails = forEachStablecoin(i => getMarketDetails(reserves[i], undefined))
const ethPrices = forEachStablecoin(i => marketDetails[i].marketRate.rateInverted)
const [median] = getMedian(ethPrices)
const [mean] = getMean(ethPrices)
const [weightedMean] = getMean(
ethPrices,
forEachStablecoin(i => reserves[i].ethReserve.amount)
)
return getMean([median, mean, weightedMean])[0]
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment