Commit f450d34d authored by Ian Lapham's avatar Ian Lapham Committed by GitHub

feat(transactions): enable button to add tokens to metamask (#1311)

* start on adding button for watching tokens

* add tokens to metamask

* add confirmation view

* reset modal view
parent 76ab349b
...@@ -7,7 +7,7 @@ import useHttpLocations from '../../hooks/useHttpLocations' ...@@ -7,7 +7,7 @@ import useHttpLocations from '../../hooks/useHttpLocations'
import { WrappedTokenInfo } from '../../state/lists/hooks' import { WrappedTokenInfo } from '../../state/lists/hooks'
import Logo from '../Logo' import Logo from '../Logo'
const getTokenLogoURL = (address: string) => export const getTokenLogoURL = (address: string) =>
`https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/${address}/logo.png` `https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/${address}/logo.png`
const StyledEthereumLogo = styled.img<{ size: string }>` const StyledEthereumLogo = styled.img<{ size: string }>`
...@@ -43,7 +43,6 @@ export default function CurrencyLogo({ ...@@ -43,7 +43,6 @@ export default function CurrencyLogo({
if (currency instanceof WrappedTokenInfo) { if (currency instanceof WrappedTokenInfo) {
return [...uriLocations, getTokenLogoURL(currency.address)] return [...uriLocations, getTokenLogoURL(currency.address)]
} }
return [getTokenLogoURL(currency.address)] return [getTokenLogoURL(currency.address)]
} }
return [] return []
......
import { ChainId } from '@uniswap/sdk' import { ChainId, Currency } from '@uniswap/sdk'
import React, { useContext } from 'react' import React, { useContext } from 'react'
import styled, { ThemeContext } from 'styled-components' import styled, { ThemeContext } from 'styled-components'
import Modal from '../Modal' import Modal from '../Modal'
import { ExternalLink } from '../../theme' import { ExternalLink } from '../../theme'
import { Text } from 'rebass' import { Text } from 'rebass'
import { CloseIcon, CustomLightSpinner } from '../../theme/components' import { CloseIcon, CustomLightSpinner } from '../../theme/components'
import { RowBetween } from '../Row' import { RowBetween, RowFixed } from '../Row'
import { AlertTriangle, ArrowUpCircle } from 'react-feather' import { AlertTriangle, ArrowUpCircle, CheckCircle } from 'react-feather'
import { ButtonPrimary } from '../Button' import { ButtonPrimary, ButtonLight } from '../Button'
import { AutoColumn, ColumnCenter } from '../Column' import { AutoColumn, ColumnCenter } from '../Column'
import Circle from '../../assets/images/blue-loader.svg' import Circle from '../../assets/images/blue-loader.svg'
import MetaMaskLogo from '../../assets/images/metamask.png'
import { getEtherscanLink } from '../../utils' import { getEtherscanLink } from '../../utils'
import { useActiveWeb3React } from '../../hooks' import { useActiveWeb3React } from '../../hooks'
import useAddTokenToMetamask from 'hooks/useAddTokenToMetamask'
const Wrapper = styled.div` const Wrapper = styled.div`
width: 100%; width: 100%;
...@@ -31,6 +32,12 @@ const ConfirmedIcon = styled(ColumnCenter)` ...@@ -31,6 +32,12 @@ const ConfirmedIcon = styled(ColumnCenter)`
padding: 60px 0; padding: 60px 0;
` `
const StyledLogo = styled.img`
height: 16px;
width: 16px;
margin-left: 6px;
`
function ConfirmationPendingContent({ onDismiss, pendingText }: { onDismiss: () => void; pendingText: string }) { function ConfirmationPendingContent({ onDismiss, pendingText }: { onDismiss: () => void; pendingText: string }) {
return ( return (
<Wrapper> <Wrapper>
...@@ -63,14 +70,20 @@ function ConfirmationPendingContent({ onDismiss, pendingText }: { onDismiss: () ...@@ -63,14 +70,20 @@ function ConfirmationPendingContent({ onDismiss, pendingText }: { onDismiss: ()
function TransactionSubmittedContent({ function TransactionSubmittedContent({
onDismiss, onDismiss,
chainId, chainId,
hash hash,
currencyToAdd
}: { }: {
onDismiss: () => void onDismiss: () => void
hash: string | undefined hash: string | undefined
chainId: ChainId chainId: ChainId
currencyToAdd?: Currency | undefined
}) { }) {
const theme = useContext(ThemeContext) const theme = useContext(ThemeContext)
const { library } = useActiveWeb3React()
const { addToken, success } = useAddTokenToMetamask(currencyToAdd)
return ( return (
<Wrapper> <Wrapper>
<Section> <Section>
...@@ -92,6 +105,20 @@ function TransactionSubmittedContent({ ...@@ -92,6 +105,20 @@ function TransactionSubmittedContent({
</Text> </Text>
</ExternalLink> </ExternalLink>
)} )}
{currencyToAdd && library?.provider?.isMetaMask && (
<ButtonLight mt="12px" padding="6px 12px" width="fit-content" onClick={addToken}>
{!success ? (
<RowFixed>
Add {currencyToAdd.symbol} to Metamask <StyledLogo src={MetaMaskLogo} />
</RowFixed>
) : (
<RowFixed>
Added {currencyToAdd.symbol}{' '}
<CheckCircle size={'16px'} stroke={theme.green1} style={{ marginLeft: '6px' }} />
</RowFixed>
)}
</ButtonLight>
)}
<ButtonPrimary onClick={onDismiss} style={{ margin: '20px 0 0 0' }}> <ButtonPrimary onClick={onDismiss} style={{ margin: '20px 0 0 0' }}>
<Text fontWeight={500} fontSize={20}> <Text fontWeight={500} fontSize={20}>
Close Close
...@@ -162,6 +189,7 @@ interface ConfirmationModalProps { ...@@ -162,6 +189,7 @@ interface ConfirmationModalProps {
content: () => React.ReactNode content: () => React.ReactNode
attemptingTxn: boolean attemptingTxn: boolean
pendingText: string pendingText: string
currencyToAdd?: Currency | undefined
} }
export default function TransactionConfirmationModal({ export default function TransactionConfirmationModal({
...@@ -170,7 +198,8 @@ export default function TransactionConfirmationModal({ ...@@ -170,7 +198,8 @@ export default function TransactionConfirmationModal({
attemptingTxn, attemptingTxn,
hash, hash,
pendingText, pendingText,
content content,
currencyToAdd
}: ConfirmationModalProps) { }: ConfirmationModalProps) {
const { chainId } = useActiveWeb3React() const { chainId } = useActiveWeb3React()
...@@ -182,7 +211,12 @@ export default function TransactionConfirmationModal({ ...@@ -182,7 +211,12 @@ export default function TransactionConfirmationModal({
{attemptingTxn ? ( {attemptingTxn ? (
<ConfirmationPendingContent onDismiss={onDismiss} pendingText={pendingText} /> <ConfirmationPendingContent onDismiss={onDismiss} pendingText={pendingText} />
) : hash ? ( ) : hash ? (
<TransactionSubmittedContent chainId={chainId} hash={hash} onDismiss={onDismiss} /> <TransactionSubmittedContent
chainId={chainId}
hash={hash}
onDismiss={onDismiss}
currencyToAdd={currencyToAdd}
/>
) : ( ) : (
content() content()
)} )}
......
...@@ -104,6 +104,7 @@ export default function ConfirmSwapModal({ ...@@ -104,6 +104,7 @@ export default function ConfirmSwapModal({
hash={txHash} hash={txHash}
content={confirmationContent} content={confirmationContent}
pendingText={pendingText} pendingText={pendingText}
currencyToAdd={trade?.outputAmount.currency}
/> />
) )
} }
import { getTokenLogoURL } from './../components/CurrencyLogo/index'
import { wrappedCurrency } from 'utils/wrappedCurrency'
import { Currency, Token } from '@uniswap/sdk'
import { useCallback, useState } from 'react'
import { useActiveWeb3React } from 'hooks'
export default function useAddTokenToMetamask(
currencyToAdd: Currency | undefined
): { addToken: () => void; success: boolean | undefined } {
const { library, chainId } = useActiveWeb3React()
const token: Token | undefined = wrappedCurrency(currencyToAdd, chainId)
const [success, setSuccess] = useState<boolean | undefined>()
const addToken = useCallback(() => {
if (library && library.provider.isMetaMask && library.provider.request && token) {
library.provider
.request({
method: 'wallet_watchAsset',
params: {
// eslint-disable-next-line @typescript-eslint/ban-ts-ignore
//@ts-ignore // need this for incorrect ethers provider type
type: 'ERC20',
options: {
address: token.address,
symbol: token.symbol,
decimals: token.decimals,
image: getTokenLogoURL(token.address)
}
}
})
.then(success => {
setSuccess(success)
})
.catch(() => setSuccess(false))
} else {
setSuccess(false)
}
}, [library, token])
return { addToken, success }
}
...@@ -328,6 +328,7 @@ export default function AddLiquidity({ ...@@ -328,6 +328,7 @@ export default function AddLiquidity({
/> />
)} )}
pendingText={pendingText} pendingText={pendingText}
currencyToAdd={pair?.liquidityToken}
/> />
<AutoColumn gap="20px"> <AutoColumn gap="20px">
{noLiquidity || {noLiquidity ||
......
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