Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[uni fix] connect and switch network (network selector) #406

Merged
merged 9 commits into from
Apr 18, 2022
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions src/custom/components/CurrencyLogo/CurrencyLogoMod.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ import styled from 'styled-components/macro'

import Logo from 'components/Logo'

export const StyledLogo = styled(Logo)<{ size: string; native: boolean }>`
export const StyledLogo = styled(Logo)<{ size: string; $native: boolean }>`
width: ${({ size }) => size};
height: ${({ size }) => size};
/* background: radial-gradient(white 50%, #ffffff00 calc(75% + 1px), #ffffff00 100%);
border-radius: 50%;
-mox-box-shadow: 0 0 1px ${({ native }) => (native ? 'white' : 'black')};
-webkit-box-shadow: 0 0 1px ${({ native }) => (native ? 'white' : 'black')};
box-shadow: 0 0 1px ${({ native }) => (native ? 'white' : 'black')};
-mox-box-shadow: 0 0 1px ${({ $native }) => ($native ? 'white' : 'black')};
-webkit-box-shadow: 0 0 1px ${({ $native }) => ($native ? 'white' : 'black')};
box-shadow: 0 0 1px ${({ $native }) => ($native ? 'white' : 'black')};
border: 0px solid rgba(255, 255, 255, 0); */
border-radius: ${({ size }) => size};
box-shadow: 0px 6px 10px rgba(0, 0, 0, 0.075);
Expand All @@ -34,7 +34,7 @@ export default function CurrencyLogo({
return (
<StyledLogo
size={size}
native={currency?.isNative ?? false}
$native={currency?.isNative ?? false}
srcs={logoURIs}
alt={`${currency?.symbol ?? 'token'} logo`}
style={style}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ import {
FlyoutHeader,
LinkOutCircle,
} from '@src/components/Header/NetworkSelector'
import useChangeNetworks from 'hooks/useChangeNetworks'
// mod
import useChangeNetworks, { ChainSwitchCallbackOptions } from 'hooks/useChangeNetworks'

/* const ActiveRowLinkList = styled.div`
display: flex;
Expand Down Expand Up @@ -204,7 +205,7 @@ function Row({
onSelectChain,
}: {
targetChain: SupportedChainId
onSelectChain: (targetChain: number) => void
onSelectChain: (targetChain: number, options: ChainSwitchCallbackOptions) => void
}) {
const { library, chainId } = useActiveWeb3React()
if (!library || !chainId) {
Expand All @@ -214,7 +215,10 @@ function Row({
const { helpCenterUrl, explorer, bridge, label, logoUrl } = CHAIN_INFO[targetChain]

const rowContent = (
<FlyoutRow onClick={() => onSelectChain(targetChain)} active={active}>
<FlyoutRow
onClick={() => onSelectChain(targetChain, { skipToggle: false, skipWalletToggle: false })}
active={active}
>
<Logo src={logoUrl} />
<NetworkLabel>{label}</NetworkLabel>
{chainId === targetChain && <FlyoutRowActiveIndicator active />}
Expand Down Expand Up @@ -267,9 +271,10 @@ export const getChainNameFromId = (id: string | number) => {
}

export default function NetworkSelector() {
const { chainId, library } = useActiveWeb3React()
// mod: add account
const { account, chainId, library } = useActiveWeb3React()
// mod: refactored inner logic into useChangeNetworks hook
const { node, open, toggle, info, handleChainSwitch } = useChangeNetworks({ chainId, library })
const { node, open, toggle, info, handleChainSwitch } = useChangeNetworks({ account, chainId, library })

/* const parsedQs = useParsedQueryString()
const { urlChain, urlChainId } = getParsedChainId(parsedQs)
Expand Down
24 changes: 11 additions & 13 deletions src/custom/constants/tokens/tokensMod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -290,19 +290,6 @@ class GnosisChainNativeCurrency extends NativeCurrency {
}
}

export class GpEther extends Ether {
public get wrapped(): Token {
if (this.chainId in WRAPPED_NATIVE_CURRENCY) return WRAPPED_NATIVE_CURRENCY[this.chainId]
throw new Error('Unsupported chain ID')
}

private static _cachedExtendedEther: { [chainId: number]: NativeCurrency } = {}

public static onChain(chainId: number): ExtendedEther {
return this._cachedExtendedEther[chainId] ?? (this._cachedExtendedEther[chainId] = new ExtendedEther(chainId))
}
}

const cachedNativeCurrency: { [chainId: number]: NativeCurrency } = {}
export function nativeOnChain(chainId: number): NativeCurrency {
return (
Expand All @@ -313,6 +300,17 @@ export function nativeOnChain(chainId: number): NativeCurrency {
)
}

export class GpEther extends Ether {
public get wrapped(): Token {
if (this.chainId in WRAPPED_NATIVE_CURRENCY) return WRAPPED_NATIVE_CURRENCY[this.chainId]
throw new Error('Unsupported chain ID')
}

private static _cachedExtendedEther: { [chainId: number]: NativeCurrency } = {}

public static onChain = nativeOnChain
alfetopito marked this conversation as resolved.
Show resolved Hide resolved
}

export const TOKEN_SHORTHANDS: { [shorthand: string]: { [chainId in SupportedChainId]?: string } } = {
USDC: {
...UNI_TOKEN_SHORTHANDS['USDC'],
Expand Down
25 changes: 0 additions & 25 deletions src/custom/hooks/useApproveCallback/useApproveCallbackMod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,31 +68,6 @@ export function useApproveCallback({
const pendingApproval = useHasPendingApproval(token?.address, spender)
const spenderCurrency = useCurrency(spender)

// TODO: Nice to have, can be deleted
// eslint-disable-next-line no-lone-blocks
W3stside marked this conversation as resolved.
Show resolved Hide resolved
{
process.env.NODE_ENV !== 'production' &&
console.debug(`
$$$$Approval metrics:
====
CurrentAllowance: ${currentAllowance?.toExact()}
raw: ${currentAllowance?.quotient.toString()}
====
amountToCheckAgainstApproval: ${amountToCheckAgainstAllowance?.toExact()}
raw: ${amountToCheckAgainstAllowance?.quotient.toString()}
====
amountToApprove: ${amountToApprove?.toExact()}
raw: ${amountToApprove?.quotient.toString()}
====
Needs approval?: ${
!amountToCheckAgainstAllowance && !amountToApprove
? 'Unknown - no amounts'
: currentAllowance && amountToApprove
? currentAllowance.lessThan(amountToCheckAgainstAllowance || amountToApprove)
: 'unknown no currentAllowance'
}
`)
}
// check the current approval status
const approvalState: ApprovalState = useMemo(() => {
if (!amountToApprove || !spender) return ApprovalState.UNKNOWN
Expand Down
107 changes: 69 additions & 38 deletions src/custom/hooks/useChangeNetworks.ts
Original file line number Diff line number Diff line change
@@ -1,82 +1,113 @@
import { useCallback, useEffect, useRef } from 'react'
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
import { useOnClickOutside } from 'hooks/useOnClickOutside'
import { useActiveWeb3React } from 'hooks/web3'
import { switchToNetwork } from 'utils/switchToNetwork'
import { useModalOpen, useToggleModal } from '../state/application/hooks'
import { useModalOpen, useToggleModal, useWalletModalToggle } from 'state/application/hooks'
import { CHAIN_INFO } from 'constants/chainInfo'
import useParsedQueryString from '@src/hooks/useParsedQueryString'
import usePrevious from '@src/hooks/usePrevious'
import { addPopup, ApplicationModal } from '@src/state/application/reducer'
import { useAppDispatch } from '@src/state/hooks'
import { replaceURLParam } from '@src/utils/routes'
import useParsedQueryString from 'hooks/useParsedQueryString'
import usePrevious from 'hooks/usePrevious'
import { addPopup, ApplicationModal } from 'state/application/reducer'
import { useAppDispatch } from 'state/hooks'
import { replaceURLParam } from 'utils/routes'
import { getChainNameFromId, getParsedChainId } from 'components/Header/NetworkSelector'
import { useHistory } from 'react-router-dom'
import { supportedChainId } from 'utils/supportedChainId'

type ChangeNetworksParams = Pick<ReturnType<typeof useActiveWeb3React>, 'chainId' | 'library'>
type ChangeNetworksParams = Pick<ReturnType<typeof useActiveWeb3React>, 'account' | 'chainId' | 'library'>
export type ChainSwitchCallbackOptions = { skipWalletToggle: boolean; skipToggle: boolean }

/**
* Hook extracted from Header/NetworkSelector component pretty much verbatim
*
* @param chainId
* @param library
*/
alfetopito marked this conversation as resolved.
Show resolved Hide resolved
export default function useChangeNetworks({ chainId, library }: ChangeNetworksParams) {
export default function useChangeNetworks({ account, chainId: preChainId, library }: ChangeNetworksParams) {
const parsedQs = useParsedQueryString()
const { urlChain, urlChainId } = getParsedChainId(parsedQs)
const prevChainId = usePrevious(chainId)
const prevChainId = usePrevious(preChainId)
const node = useRef<HTMLDivElement>()
const open = useModalOpen(ApplicationModal.NETWORK_SELECTOR)
const toggle = useToggleModal(ApplicationModal.NETWORK_SELECTOR)
useOnClickOutside(node, open ? toggle : undefined)

const history = useHistory()

const info = chainId ? CHAIN_INFO[chainId] : undefined

const dispatch = useAppDispatch()

const toggleWalletModal = useWalletModalToggle() // MOD
const [queuedNetworkSwitch, setQueuedNetworkSwitch] = useState<null | number>(null) // MOD
// MOD: get supported chain and check unsupported
const chainId = useMemo(() => {
const chainId = supportedChainId(preChainId)

return chainId
}, [preChainId])
W3stside marked this conversation as resolved.
Show resolved Hide resolved

const info = chainId ? CHAIN_INFO[chainId] : undefined

const handleChainSwitch = useCallback(
(targetChain: number, skipToggle?: boolean) => {
(targetChain: number, options: ChainSwitchCallbackOptions) => {
if (!library) return
switchToNetwork({ library, chainId: targetChain })
.then(() => {
if (!skipToggle) {
toggle()
}
history.replace({
search: replaceURLParam(history.location.search, 'chain', getChainNameFromId(targetChain)),
// mod
if (!account && !options.skipWalletToggle) {
toggleWalletModal()
return setQueuedNetworkSwitch(targetChain)
} else {
switchToNetwork({ library, chainId: targetChain })
.then(() => {
// mod
if (!options.skipToggle) {
toggle()
}
history.replace({
search: replaceURLParam(history.location.search, 'chain', getChainNameFromId(targetChain)),
})
})
})
.catch((error) => {
console.error('Failed to switch networks', error)
.catch((error) => {
console.error('Failed to switch networks', error)

// we want app network <-> chainId param to be in sync, so if user changes the network by changing the URL
// but the request fails, revert the URL back to current chainId
if (chainId) {
history.replace({ search: replaceURLParam(history.location.search, 'chain', getChainNameFromId(chainId)) })
}
// we want app network <-> chainId param to be in sync, so if user changes the network by changing the URL
// but the request fails, revert the URL back to current chainId
if (chainId) {
history.replace({
search: replaceURLParam(history.location.search, 'chain', getChainNameFromId(chainId)),
})
}
// mod
if (!options.skipToggle) {
toggle()
}

if (!skipToggle) {
toggle()
}

dispatch(addPopup({ content: { failedSwitchNetwork: targetChain }, key: `failed-network-switch` }))
})
dispatch(addPopup({ content: { failedSwitchNetwork: targetChain }, key: `failed-network-switch` }))
})
}
},
[dispatch, library, toggle, history, chainId]
[dispatch, library, toggle, history, chainId, account, toggleWalletModal]
)

// MOD
// handle the network switch on queued detection
useEffect(() => {
if (queuedNetworkSwitch && account && chainId) {
handleChainSwitch(queuedNetworkSwitch, { skipToggle: true, skipWalletToggle: false })
setQueuedNetworkSwitch(null)
}
}, [queuedNetworkSwitch, chainId, account, handleChainSwitch])

useEffect(() => {
if (!chainId || !prevChainId) return

// when network change originates from wallet or dropdown selector, just update URL
if (chainId !== prevChainId) {
history.replace({ search: replaceURLParam(history.location.search, 'chain', getChainNameFromId(chainId)) })
// otherwise assume network change originates from URL
} else if (urlChainId && urlChainId !== chainId) {
handleChainSwitch(urlChainId, true)
// } else if (urlChainId && urlChainId !== chainId) {
} else if (!queuedNetworkSwitch && urlChainId && urlChainId !== chainId) {
// handleChainSwitch(urlChainId, true)
handleChainSwitch(urlChainId, { skipToggle: true, skipWalletToggle: false }) // MOD
}
}, [chainId, urlChainId, prevChainId, handleChainSwitch, history])
}, [chainId, urlChainId, prevChainId, handleChainSwitch, history, queuedNetworkSwitch, urlChain])

// set chain parameter on initial load if not there
useEffect(() => {
Expand Down
4 changes: 0 additions & 4 deletions src/custom/pages/App/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import * as Sentry from '@sentry/react'
import { Integrations } from '@sentry/tracing'
import { version } from '@src/../package.json'
import { environmentName } from 'utils/environments'
import { useFilterEmptyQueryParams } from 'hooks/useFilterEmptyQueryParams'
import RedirectAnySwapAffectedUsers from 'pages/error/AnySwapAffectedUsers/RedirectAnySwapAffectedUsers'
import { SENTRY_IGNORED_GP_QUOTE_ERRORS } from 'api/gnosisProtocol/errors/QuoteError'

Expand Down Expand Up @@ -89,9 +88,6 @@ function createRedirectExternal(url: string) {
const Loading = <LoadingWrapper>Loading...</LoadingWrapper>

export default function App() {
// Dealing with empty URL queryParameters
useFilterEmptyQueryParams()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't it break anything else in the app?
I mean, it must have had a reason to be added, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nyehhh


return (
<>
<RedirectAnySwapAffectedUsers />
Expand Down
3 changes: 2 additions & 1 deletion src/custom/pages/Claim/ClaimsOnOtherChainsBanner.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,8 @@ function ClaimsOnOtherChainsBanner({ className }: { className?: string }) {
<div>This account has available claims on</div>
<div>
{chainsWithClaims.map((chainId, index, array) => {
const changeNetworksCallback = () => handleChainSwitch(chainId, true) // true to avoid opening the dropdown
const changeNetworksCallback = () =>
handleChainSwitch(chainId, { skipToggle: true, skipWalletToggle: false }) // true to avoid opening the dropdown
const isLastInMultiple = index === array.length - 1 && array.length > 1
return (
<Fragment key={chainId}>
Expand Down