Commit f41580e4 authored by lynn's avatar lynn Committed by GitHub

feat: implement connect wallet category events (#4111)

* init commit

* wallet connected event init commit

* add received_swap_quote event property

* add page context, connect wallet event log

* add received_swap_quote property

* fix typo

* respond to cmcewen comments

* respond to vm comments

* move trace to app.tsx from header

* respond to vm comments
parent 47fe9911
...@@ -5,14 +5,22 @@ ...@@ -5,14 +5,22 @@
* and logged. * and logged.
*/ */
export enum EventName { export enum EventName {
CONNECT_WALLET_BUTTON_CLICKED = 'Connect Wallet Button Clicked',
PAGE_VIEWED = 'Page Viewed', PAGE_VIEWED = 'Page Viewed',
SWAP_SUBMITTED = 'Swap Submitted', SWAP_SUBMITTED = 'Swap Submitted',
TOKEN_IMPORTED = 'Token Imported', TOKEN_IMPORTED = 'Token Imported',
TOKEN_SELECTED = 'Token Selected', TOKEN_SELECTED = 'Token Selected',
TOKEN_SELECTOR_OPENED = 'Token Selector Opened', TOKEN_SELECTOR_OPENED = 'Token Selector Opened',
WALLET_CONNECT_TXN_COMPLETED = 'Wallet Connect Transaction Completed',
WALLET_SELECTED = 'Wallet Selected',
// alphabetize additional event names. // alphabetize additional event names.
} }
export enum WALLET_CONNECTION_RESULT {
SUCCEEDED = 'Succeeded',
FAILED = 'Failed',
}
/** /**
* Known pages in the app. Highest order context. * Known pages in the app. Highest order context.
*/ */
...@@ -49,9 +57,11 @@ export const enum ModalName { ...@@ -49,9 +57,11 @@ export const enum ModalName {
export const enum ElementName { export const enum ElementName {
COMMON_BASES_CURRENCY_BUTTON = 'common-bases-currency-button', COMMON_BASES_CURRENCY_BUTTON = 'common-bases-currency-button',
CONFIRM_SWAP_BUTTON = 'confirm-swap-or-send', CONFIRM_SWAP_BUTTON = 'confirm-swap-or-send',
CONNECT_WALLET_BUTTON = 'connect-wallet-button',
IMPORT_TOKEN_BUTTON = 'import-token-button', IMPORT_TOKEN_BUTTON = 'import-token-button',
SWAP_BUTTON = 'swap-button', SWAP_BUTTON = 'swap-button',
TOKEN_SELECTOR_ROW = 'token-selector-row', TOKEN_SELECTOR_ROW = 'token-selector-row',
WALLET_TYPE_OPTION = 'wallet-type-option',
// alphabetize additional element names. // alphabetize additional element names.
} }
......
import { ElementName, Event, EventName } from 'components/AmplitudeAnalytics/constants'
import { TraceEvent } from 'components/AmplitudeAnalytics/TraceEvent'
import React from 'react' import React from 'react'
import styled from 'styled-components/macro' import styled from 'styled-components/macro'
...@@ -112,32 +114,39 @@ export default function Option({ ...@@ -112,32 +114,39 @@ export default function Option({
id: string id: string
}) { }) {
const content = ( const content = (
<OptionCardClickable <TraceEvent
id={id} events={[Event.onClick]}
onClick={onClick} name={EventName.WALLET_SELECTED}
clickable={clickable && !isActive} properties={{ wallet_type: header }}
active={isActive} element={ElementName.WALLET_TYPE_OPTION}
data-testid="wallet-modal-option"
> >
<OptionCardLeft> <OptionCardClickable
<HeaderText color={color}> id={id}
{isActive ? ( onClick={onClick}
<CircleWrapper> clickable={clickable && !isActive}
<GreenCircle> active={isActive}
<div /> data-testid="wallet-modal-option"
</GreenCircle> >
</CircleWrapper> <OptionCardLeft>
) : ( <HeaderText color={color}>
'' {isActive ? (
)} <CircleWrapper>
{header} <GreenCircle>
</HeaderText> <div />
{subheader && <SubHeader>{subheader}</SubHeader>} </GreenCircle>
</OptionCardLeft> </CircleWrapper>
<IconWrapper size={size}> ) : (
<img src={icon} alt={'Icon'} /> ''
</IconWrapper> )}
</OptionCardClickable> {header}
</HeaderText>
{subheader && <SubHeader>{subheader}</SubHeader>}
</OptionCardLeft>
<IconWrapper size={size}>
<img src={icon} alt={'Icon'} />
</IconWrapper>
</OptionCardClickable>
</TraceEvent>
) )
if (link) { if (link) {
return <ExternalLink href={link}>{content}</ExternalLink> return <ExternalLink href={link}>{content}</ExternalLink>
......
import { Trans } from '@lingui/macro' import { Trans } from '@lingui/macro'
import { useWeb3React } from '@web3-react/core' import { useWeb3React } from '@web3-react/core'
import { Connector } from '@web3-react/types' import { Connector } from '@web3-react/types'
import { sendAnalyticsEvent } from 'components/AmplitudeAnalytics'
import { EventName, WALLET_CONNECTION_RESULT } from 'components/AmplitudeAnalytics/constants'
import { sendEvent } from 'components/analytics' import { sendEvent } from 'components/analytics'
import { AutoColumn } from 'components/Column' import { AutoColumn } from 'components/Column'
import { AutoRow } from 'components/Row' import { AutoRow } from 'components/Row'
import { ConnectionType } from 'connection' import { ConnectionType } from 'connection'
import { getConnection, getIsCoinbaseWallet, getIsInjected, getIsMetaMask } from 'connection/utils' import { getConnection, getConnectionName, getIsCoinbaseWallet, getIsInjected, getIsMetaMask } from 'connection/utils'
import { useCallback, useEffect, useState } from 'react' import { useCallback, useEffect, useState } from 'react'
import { ArrowLeft } from 'react-feather' import { ArrowLeft } from 'react-feather'
import { updateConnectionError } from 'state/connection/reducer' import { updateConnectionError } from 'state/connection/reducer'
...@@ -121,9 +123,10 @@ export default function WalletModal({ ...@@ -121,9 +123,10 @@ export default function WalletModal({
ENSName?: string ENSName?: string
}) { }) {
const dispatch = useAppDispatch() const dispatch = useAppDispatch()
const { account } = useWeb3React() const { connector, account } = useWeb3React()
const [walletView, setWalletView] = useState(WALLET_VIEWS.ACCOUNT) const [walletView, setWalletView] = useState(WALLET_VIEWS.ACCOUNT)
const [lastActiveWalletAddress, setLastActiveWalletAddress] = useState<string | undefined>(account)
const [pendingConnector, setPendingConnector] = useState<Connector | undefined>() const [pendingConnector, setPendingConnector] = useState<Connector | undefined>()
const pendingError = useAppSelector((state) => const pendingError = useAppSelector((state) =>
...@@ -150,6 +153,19 @@ export default function WalletModal({ ...@@ -150,6 +153,19 @@ export default function WalletModal({
} }
}, [pendingConnector, walletView]) }, [pendingConnector, walletView])
// When new wallet is successfully set by the user, trigger logging of Amplitude analytics event.
useEffect(() => {
if (account && account !== lastActiveWalletAddress) {
sendAnalyticsEvent(EventName.WALLET_CONNECT_TXN_COMPLETED, {
result: WALLET_CONNECTION_RESULT.SUCCEEDED,
wallet_address: account,
wallet_type: getConnectionName(getConnection(connector).type, getIsMetaMask()),
// TODO(lynnshaoyu): Send correct is_reconnect value after modifying user state.
})
}
setLastActiveWalletAddress(account)
}, [lastActiveWalletAddress, account, connector])
const tryActivation = useCallback( const tryActivation = useCallback(
async (connector: Connector) => { async (connector: Connector) => {
const connectionType = getConnection(connector).type const connectionType = getConnection(connector).type
...@@ -178,6 +194,11 @@ export default function WalletModal({ ...@@ -178,6 +194,11 @@ export default function WalletModal({
} catch (error) { } catch (error) {
console.debug(`web3-react connection error: ${error}`) console.debug(`web3-react connection error: ${error}`)
dispatch(updateConnectionError({ connectionType, error: error.message })) dispatch(updateConnectionError({ connectionType, error: error.message }))
sendAnalyticsEvent(EventName.WALLET_CONNECT_TXN_COMPLETED, {
result: WALLET_CONNECTION_RESULT.FAILED,
wallet_type: getConnectionName(connectionType, getIsMetaMask()),
})
} }
}, },
[dispatch, toggleWalletModal] [dispatch, toggleWalletModal]
......
// eslint-disable-next-line no-restricted-imports // eslint-disable-next-line no-restricted-imports
import { t, Trans } from '@lingui/macro' import { t, Trans } from '@lingui/macro'
import { useWeb3React } from '@web3-react/core' import { useWeb3React } from '@web3-react/core'
import { ElementName, Event, EventName } from 'components/AmplitudeAnalytics/constants'
import { TraceEvent } from 'components/AmplitudeAnalytics/TraceEvent'
import { getConnection } from 'connection/utils' import { getConnection } from 'connection/utils'
import { getIsValidSwapQuote } from 'pages/Swap'
import { darken } from 'polished' import { darken } from 'polished'
import { useMemo } from 'react' import { useMemo } from 'react'
import { Activity } from 'react-feather' import { Activity } from 'react-feather'
import { useAppSelector } from 'state/hooks' import { useAppSelector } from 'state/hooks'
import { useDerivedSwapInfo } from 'state/swap/hooks'
import styled, { css } from 'styled-components/macro' import styled, { css } from 'styled-components/macro'
import { isChainAllowed } from 'utils/switchChain' import { isChainAllowed } from 'utils/switchChain'
...@@ -123,6 +127,11 @@ function Sock() { ...@@ -123,6 +127,11 @@ function Sock() {
function Web3StatusInner() { function Web3StatusInner() {
const { account, connector, chainId, ENSName } = useWeb3React() const { account, connector, chainId, ENSName } = useWeb3React()
const connectionType = getConnection(connector).type const connectionType = getConnection(connector).type
const {
trade: { state: tradeState, trade },
inputError: swapInputError,
} = useDerivedSwapInfo()
const validSwapQuote = getIsValidSwapQuote(trade, tradeState, swapInputError)
const error = useAppSelector((state) => state.connection.errorByConnectionType[getConnection(connector).type]) const error = useAppSelector((state) => state.connection.errorByConnectionType[getConnection(connector).type])
...@@ -186,11 +195,18 @@ function Web3StatusInner() { ...@@ -186,11 +195,18 @@ function Web3StatusInner() {
) )
} else { } else {
return ( return (
<Web3StatusConnect onClick={toggleWalletModal} faded={!account}> <TraceEvent
<Text> events={[Event.onClick]}
<Trans>Connect Wallet</Trans> name={EventName.CONNECT_WALLET_BUTTON_CLICKED}
</Text> properties={{ received_swap_quote: validSwapQuote }}
</Web3StatusConnect> element={ElementName.CONNECT_WALLET_BUTTON}
>
<Web3StatusConnect onClick={toggleWalletModal} faded={!account}>
<Text>
<Trans>Connect Wallet</Trans>
</Text>
</Web3StatusConnect>
</TraceEvent>
) )
} }
} }
......
...@@ -4,6 +4,8 @@ import { Trans } from '@lingui/macro' ...@@ -4,6 +4,8 @@ import { Trans } from '@lingui/macro'
import { Currency, CurrencyAmount, Percent } from '@uniswap/sdk-core' import { Currency, CurrencyAmount, Percent } from '@uniswap/sdk-core'
import { FeeAmount, NonfungiblePositionManager } from '@uniswap/v3-sdk' import { FeeAmount, NonfungiblePositionManager } from '@uniswap/v3-sdk'
import { useWeb3React } from '@web3-react/core' import { useWeb3React } from '@web3-react/core'
import { ElementName, Event, EventName } from 'components/AmplitudeAnalytics/constants'
import { TraceEvent } from 'components/AmplitudeAnalytics/TraceEvent'
import { sendEvent } from 'components/analytics' import { sendEvent } from 'components/analytics'
import UnsupportedCurrencyFooter from 'components/swap/UnsupportedCurrencyFooter' import UnsupportedCurrencyFooter from 'components/swap/UnsupportedCurrencyFooter'
import useParsedQueryString from 'hooks/useParsedQueryString' import useParsedQueryString from 'hooks/useParsedQueryString'
...@@ -433,9 +435,16 @@ export default function AddLiquidity({ ...@@ -433,9 +435,16 @@ export default function AddLiquidity({
</ThemedText.Main> </ThemedText.Main>
</ButtonPrimary> </ButtonPrimary>
) : !account ? ( ) : !account ? (
<ButtonLight onClick={toggleWalletModal} $borderRadius="12px" padding={'12px'}> <TraceEvent
<Trans>Connect Wallet</Trans> events={[Event.onClick]}
</ButtonLight> name={EventName.CONNECT_WALLET_BUTTON_CLICKED}
properties={{ received_swap_quote: false }}
element={ElementName.CONNECT_WALLET_BUTTON}
>
<ButtonLight onClick={toggleWalletModal} $borderRadius="12px" padding={'12px'}>
<Trans>Connect Wallet</Trans>
</ButtonLight>
</TraceEvent>
) : ( ) : (
<AutoColumn gap={'md'}> <AutoColumn gap={'md'}>
{(approvalA === ApprovalState.NOT_APPROVED || {(approvalA === ApprovalState.NOT_APPROVED ||
......
...@@ -3,6 +3,8 @@ import { TransactionResponse } from '@ethersproject/providers' ...@@ -3,6 +3,8 @@ import { TransactionResponse } from '@ethersproject/providers'
import { Trans } from '@lingui/macro' import { Trans } from '@lingui/macro'
import { Currency, CurrencyAmount, Percent } from '@uniswap/sdk-core' import { Currency, CurrencyAmount, Percent } from '@uniswap/sdk-core'
import { useWeb3React } from '@web3-react/core' import { useWeb3React } from '@web3-react/core'
import { ElementName, Event, EventName } from 'components/AmplitudeAnalytics/constants'
import { TraceEvent } from 'components/AmplitudeAnalytics/TraceEvent'
import { sendEvent } from 'components/analytics' import { sendEvent } from 'components/analytics'
import UnsupportedCurrencyFooter from 'components/swap/UnsupportedCurrencyFooter' import UnsupportedCurrencyFooter from 'components/swap/UnsupportedCurrencyFooter'
import { SwitchLocaleLink } from 'components/SwitchLocaleLink' import { SwitchLocaleLink } from 'components/SwitchLocaleLink'
...@@ -435,9 +437,16 @@ export default function AddLiquidity({ ...@@ -435,9 +437,16 @@ export default function AddLiquidity({
</ThemedText.Main> </ThemedText.Main>
</ButtonPrimary> </ButtonPrimary>
) : !account ? ( ) : !account ? (
<ButtonLight onClick={toggleWalletModal}> <TraceEvent
<Trans>Connect Wallet</Trans> events={[Event.onClick]}
</ButtonLight> name={EventName.CONNECT_WALLET_BUTTON_CLICKED}
properties={{ received_swap_quote: false }}
element={ElementName.CONNECT_WALLET_BUTTON}
>
<ButtonLight onClick={toggleWalletModal}>
<Trans>Connect Wallet</Trans>
</ButtonLight>
</TraceEvent>
) : ( ) : (
<AutoColumn gap={'md'}> <AutoColumn gap={'md'}>
{(approvalA === ApprovalState.NOT_APPROVED || {(approvalA === ApprovalState.NOT_APPROVED ||
......
import { initializeAnalytics } from 'components/AmplitudeAnalytics' import { initializeAnalytics } from 'components/AmplitudeAnalytics'
import { PageName } from 'components/AmplitudeAnalytics/constants'
import { Trace } from 'components/AmplitudeAnalytics/Trace'
import Loader from 'components/Loader' import Loader from 'components/Loader'
import TopLevelModals from 'components/TopLevelModals' import TopLevelModals from 'components/TopLevelModals'
import ApeModeQueryParamReader from 'hooks/useApeModeQueryParamReader' import ApeModeQueryParamReader from 'hooks/useApeModeQueryParamReader'
...@@ -64,8 +66,23 @@ const Marginer = styled.div` ...@@ -64,8 +66,23 @@ const Marginer = styled.div`
margin-top: 5rem; margin-top: 5rem;
` `
function getCurrentPageFromLocation(locationPathname: string): PageName | undefined {
switch (locationPathname) {
case '/swap':
return PageName.SWAP_PAGE
case '/vote':
return PageName.VOTE_PAGE
case '/pool':
return PageName.POOL_PAGE
default:
return undefined
}
}
export default function App() { export default function App() {
const history = useHistory() const history = useHistory()
const location = useLocation()
const currentPage = getCurrentPageFromLocation(location.pathname)
useAnalyticsReporter(useLocation()) useAnalyticsReporter(useLocation())
initializeAnalytics() initializeAnalytics()
...@@ -83,58 +100,65 @@ export default function App() { ...@@ -83,58 +100,65 @@ export default function App() {
<Route component={DarkModeQueryParamReader} /> <Route component={DarkModeQueryParamReader} />
<Route component={ApeModeQueryParamReader} /> <Route component={ApeModeQueryParamReader} />
<AppWrapper> <AppWrapper>
<HeaderWrapper> <Trace page={currentPage}>
<Header /> <HeaderWrapper>
</HeaderWrapper> <Header />
<BodyWrapper> </HeaderWrapper>
<Popups /> <BodyWrapper>
<Polling /> <Popups />
<TopLevelModals /> <Polling />
<Suspense fallback={<Loader />}> <TopLevelModals />
<Switch> <Suspense fallback={<Loader />}>
<Route strict path="/vote" component={Vote} /> <Switch>
<Route exact strict path="/create-proposal"> <Route path="/vote" component={Vote} />
<Redirect to="/vote/create-proposal" /> <Route exact strict path="/create-proposal">
</Route> <Redirect to="/vote/create-proposal" />
<Route exact strict path="/claim" component={OpenClaimAddressModalAndRedirectToSwap} /> </Route>
<Route exact strict path="/uni" component={Earn} /> <Route exact strict path="/claim" component={OpenClaimAddressModalAndRedirectToSwap} />
<Route exact strict path="/uni/:currencyIdA/:currencyIdB" component={Manage} /> <Route exact strict path="/uni" component={Earn} />
<Route exact strict path="/uni/:currencyIdA/:currencyIdB" component={Manage} />
<Route exact strict path="/send" component={RedirectPathToSwapOnly} />
<Route exact strict path="/swap/:outputCurrency" component={RedirectToSwap} /> <Route exact strict path="/send" component={RedirectPathToSwapOnly} />
<Route exact strict path="/swap" component={Swap} /> <Route exact strict path="/swap/:outputCurrency" component={RedirectToSwap} />
<Route path="/swap" component={Swap} />
<Route exact strict path="/pool/v2/find" component={PoolFinder} />
<Route exact strict path="/pool/v2" component={PoolV2} /> <Route exact strict path="/pool/v2/find" component={PoolFinder} />
<Route exact strict path="/pool" component={Pool} /> <Route exact strict path="/pool/v2" component={PoolV2} />
<Route exact strict path="/pool/:tokenId" component={PositionPage} /> <Route exact strict path="/pool" component={Pool} />
<Route exact strict path="/pool/:tokenId" component={PositionPage} />
<Route exact strict path="/add/v2/:currencyIdA?/:currencyIdB?" component={RedirectDuplicateTokenIdsV2} />
<Route <Route
exact exact
strict strict
path="/add/:currencyIdA?/:currencyIdB?/:feeAmount?" path="/add/v2/:currencyIdA?/:currencyIdB?"
component={RedirectDuplicateTokenIds} component={RedirectDuplicateTokenIdsV2}
/> />
<Route
<Route exact
exact strict
strict path="/add/:currencyIdA?/:currencyIdB?/:feeAmount?"
path="/increase/:currencyIdA?/:currencyIdB?/:feeAmount?/:tokenId?" component={RedirectDuplicateTokenIds}
component={AddLiquidity} />
/>
<Route
<Route exact strict path="/remove/v2/:currencyIdA/:currencyIdB" component={RemoveLiquidity} /> exact
<Route exact strict path="/remove/:tokenId" component={RemoveLiquidityV3} /> strict
path="/increase/:currencyIdA?/:currencyIdB?/:feeAmount?/:tokenId?"
<Route exact strict path="/migrate/v2" component={MigrateV2} /> component={AddLiquidity}
<Route exact strict path="/migrate/v2/:address" component={MigrateV2Pair} /> />
<Route component={RedirectPathToSwapOnly} /> <Route exact strict path="/remove/v2/:currencyIdA/:currencyIdB" component={RemoveLiquidity} />
</Switch> <Route exact strict path="/remove/:tokenId" component={RemoveLiquidityV3} />
</Suspense>
<Marginer /> <Route exact strict path="/migrate/v2" component={MigrateV2} />
</BodyWrapper> <Route exact strict path="/migrate/v2/:address" component={MigrateV2Pair} />
<Route component={RedirectPathToSwapOnly} />
</Switch>
</Suspense>
<Marginer />
</BodyWrapper>
</Trace>
</AppWrapper> </AppWrapper>
</ErrorBoundary> </ErrorBoundary>
) )
......
import { Trans } from '@lingui/macro' import { Trans } from '@lingui/macro'
import { useWeb3React } from '@web3-react/core' import { useWeb3React } from '@web3-react/core'
import { PageName } from 'components/AmplitudeAnalytics/constants' import { PageName } from 'components/AmplitudeAnalytics/constants'
import { ElementName, Event, EventName } from 'components/AmplitudeAnalytics/constants'
import { Trace } from 'components/AmplitudeAnalytics/Trace' import { Trace } from 'components/AmplitudeAnalytics/Trace'
import { TraceEvent } from 'components/AmplitudeAnalytics/TraceEvent'
import { ButtonGray, ButtonPrimary, ButtonText } from 'components/Button' import { ButtonGray, ButtonPrimary, ButtonText } from 'components/Button'
import { AutoColumn } from 'components/Column' import { AutoColumn } from 'components/Column'
import { FlyoutAlignment, NewMenu } from 'components/Menu' import { FlyoutAlignment, NewMenu } from 'components/Menu'
...@@ -311,9 +313,16 @@ export default function Pool() { ...@@ -311,9 +313,16 @@ export default function Pool() {
</ButtonText> </ButtonText>
)} )}
{showConnectAWallet && ( {showConnectAWallet && (
<ButtonPrimary style={{ marginTop: '2em', padding: '8px 16px' }} onClick={toggleWalletModal}> <TraceEvent
<Trans>Connect a wallet</Trans> events={[Event.onClick]}
</ButtonPrimary> name={EventName.CONNECT_WALLET_BUTTON_CLICKED}
properties={{ received_swap_quote: false }}
element={ElementName.CONNECT_WALLET_BUTTON}
>
<ButtonPrimary style={{ marginTop: '2em', padding: '8px 16px' }} onClick={toggleWalletModal}>
<Trans>Connect a wallet</Trans>
</ButtonPrimary>
</TraceEvent>
)} )}
</ErrorContainer> </ErrorContainer>
)} )}
......
...@@ -4,6 +4,8 @@ import { TransactionResponse } from '@ethersproject/providers' ...@@ -4,6 +4,8 @@ import { TransactionResponse } from '@ethersproject/providers'
import { Trans } from '@lingui/macro' import { Trans } from '@lingui/macro'
import { Currency, Percent } from '@uniswap/sdk-core' import { Currency, Percent } from '@uniswap/sdk-core'
import { useWeb3React } from '@web3-react/core' import { useWeb3React } from '@web3-react/core'
import { ElementName, Event, EventName } from 'components/AmplitudeAnalytics/constants'
import { TraceEvent } from 'components/AmplitudeAnalytics/TraceEvent'
import { sendEvent } from 'components/analytics' import { sendEvent } from 'components/analytics'
import { useV2LiquidityTokenPermit } from 'hooks/useV2LiquidityTokenPermit' import { useV2LiquidityTokenPermit } from 'hooks/useV2LiquidityTokenPermit'
import { useCallback, useContext, useMemo, useState } from 'react' import { useCallback, useContext, useMemo, useState } from 'react'
...@@ -625,9 +627,16 @@ export default function RemoveLiquidity({ ...@@ -625,9 +627,16 @@ export default function RemoveLiquidity({
)} )}
<div style={{ position: 'relative' }}> <div style={{ position: 'relative' }}>
{!account ? ( {!account ? (
<ButtonLight onClick={toggleWalletModal}> <TraceEvent
<Trans>Connect Wallet</Trans> events={[Event.onClick]}
</ButtonLight> name={EventName.CONNECT_WALLET_BUTTON_CLICKED}
properties={{ received_swap_quote: false }}
element={ElementName.CONNECT_WALLET_BUTTON}
>
<ButtonLight onClick={toggleWalletModal}>
<Trans>Connect Wallet</Trans>
</ButtonLight>
</TraceEvent>
) : ( ) : (
<RowBetween> <RowBetween>
<ButtonConfirmed <ButtonConfirmed
......
...@@ -4,8 +4,10 @@ import { Currency, CurrencyAmount, Token, TradeType } from '@uniswap/sdk-core' ...@@ -4,8 +4,10 @@ import { Currency, CurrencyAmount, Token, TradeType } from '@uniswap/sdk-core'
import { Trade as V2Trade } from '@uniswap/v2-sdk' import { Trade as V2Trade } from '@uniswap/v2-sdk'
import { Trade as V3Trade } from '@uniswap/v3-sdk' import { Trade as V3Trade } from '@uniswap/v3-sdk'
import { useWeb3React } from '@web3-react/core' import { useWeb3React } from '@web3-react/core'
import { ElementName, Event, EventName } from 'components/AmplitudeAnalytics/constants'
import { PageName, SectionName } from 'components/AmplitudeAnalytics/constants' import { PageName, SectionName } from 'components/AmplitudeAnalytics/constants'
import { Trace } from 'components/AmplitudeAnalytics/Trace' import { Trace } from 'components/AmplitudeAnalytics/Trace'
import { TraceEvent } from 'components/AmplitudeAnalytics/TraceEvent'
import { sendEvent } from 'components/analytics' import { sendEvent } from 'components/analytics'
import { NetworkAlert } from 'components/NetworkAlert/NetworkAlert' import { NetworkAlert } from 'components/NetworkAlert/NetworkAlert'
import SwapDetailsDropdown from 'components/swap/SwapDetailsDropdown' import SwapDetailsDropdown from 'components/swap/SwapDetailsDropdown'
...@@ -15,9 +17,12 @@ import { useSwapCallback } from 'hooks/useSwapCallback' ...@@ -15,9 +17,12 @@ import { useSwapCallback } from 'hooks/useSwapCallback'
import useTransactionDeadline from 'hooks/useTransactionDeadline' import useTransactionDeadline from 'hooks/useTransactionDeadline'
import JSBI from 'jsbi' import JSBI from 'jsbi'
import { Context, useCallback, useContext, useEffect, useMemo, useState } from 'react' import { Context, useCallback, useContext, useEffect, useMemo, useState } from 'react'
import { ReactNode } from 'react'
import { ArrowDown, CheckCircle, HelpCircle } from 'react-feather' import { ArrowDown, CheckCircle, HelpCircle } from 'react-feather'
import { RouteComponentProps } from 'react-router-dom' import { RouteComponentProps } from 'react-router-dom'
import { Text } from 'rebass' import { Text } from 'rebass'
import { useToggleWalletModal } from 'state/application/hooks'
import { InterfaceTrade } from 'state/routing/types'
import { TradeState } from 'state/routing/types' import { TradeState } from 'state/routing/types'
import styled, { DefaultTheme, ThemeContext } from 'styled-components/macro' import styled, { DefaultTheme, ThemeContext } from 'styled-components/macro'
...@@ -44,7 +49,6 @@ import useIsArgentWallet from '../../hooks/useIsArgentWallet' ...@@ -44,7 +49,6 @@ import useIsArgentWallet from '../../hooks/useIsArgentWallet'
import { useIsSwapUnsupported } from '../../hooks/useIsSwapUnsupported' import { useIsSwapUnsupported } from '../../hooks/useIsSwapUnsupported'
import { useStablecoinValue } from '../../hooks/useStablecoinPrice' import { useStablecoinValue } from '../../hooks/useStablecoinPrice'
import useWrapCallback, { WrapErrorText, WrapType } from '../../hooks/useWrapCallback' import useWrapCallback, { WrapErrorText, WrapType } from '../../hooks/useWrapCallback'
import { useToggleWalletModal } from '../../state/application/hooks'
import { Field } from '../../state/swap/actions' import { Field } from '../../state/swap/actions'
import { import {
useDefaultsFromURLSearch, useDefaultsFromURLSearch,
...@@ -65,6 +69,14 @@ const AlertWrapper = styled.div` ...@@ -65,6 +69,14 @@ const AlertWrapper = styled.div`
width: 100%; width: 100%;
` `
export function getIsValidSwapQuote(
trade: InterfaceTrade<Currency, Currency, TradeType> | undefined,
tradeState: TradeState,
swapInputError?: ReactNode
): boolean {
return !!swapInputError && !!trade && (tradeState === TradeState.VALID || tradeState === TradeState.SYNCING)
}
export default function Swap({ history }: RouteComponentProps) { export default function Swap({ history }: RouteComponentProps) {
const { account, chainId } = useWeb3React() const { account, chainId } = useWeb3React()
const loadedUrlParams = useDefaultsFromURLSearch() const loadedUrlParams = useDefaultsFromURLSearch()
...@@ -510,9 +522,16 @@ export default function Swap({ history }: RouteComponentProps) { ...@@ -510,9 +522,16 @@ export default function Swap({ history }: RouteComponentProps) {
</ThemedText.Main> </ThemedText.Main>
</ButtonPrimary> </ButtonPrimary>
) : !account ? ( ) : !account ? (
<ButtonLight onClick={toggleWalletModal}> <TraceEvent
<Trans>Connect Wallet</Trans> events={[Event.onClick]}
</ButtonLight> name={EventName.CONNECT_WALLET_BUTTON_CLICKED}
properties={{ received_swap_quote: getIsValidSwapQuote(trade, tradeState, swapInputError) }}
element={ElementName.CONNECT_WALLET_BUTTON}
>
<ButtonLight onClick={toggleWalletModal}>
<Trans>Connect Wallet</Trans>
</ButtonLight>
</TraceEvent>
) : showWrap ? ( ) : showWrap ? (
<ButtonPrimary disabled={Boolean(wrapInputError)} onClick={onWrap}> <ButtonPrimary disabled={Boolean(wrapInputError)} onClick={onWrap}>
{wrapInputError ? ( {wrapInputError ? (
......
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