import { BigNumber } from '@ethersproject/bignumber'
import { formatEther } from '@ethersproject/units'
import type { Web3ReactHooks } from '@web3-react/core'
import { Frame } from '@web3-react/frame'
import { Magic } from '@web3-react/magic'
import { MetaMask } from '@web3-react/metamask'
import { Network } from '@web3-react/network'
import type { Connector } from '@web3-react/types'
import { WalletConnect } from '@web3-react/walletconnect'
import { WalletLink } from '@web3-react/walletlink'
import { useCallback, useEffect, useState } from 'react'
import { CHAINS, getAddChainParameters, URLS } from './chains'
import { connectors } from './connectors'
function getName(connector: Connector) {
if (connector instanceof Frame) {
return 'Frame (Experimental)'
} else if (connector instanceof Magic) {
return 'Magic (Experimental)'
} else if (connector instanceof MetaMask) {
return 'MetaMask'
} else if (connector instanceof Network) {
return 'Network'
} else if (connector instanceof WalletConnect) {
return 'WalletConnect'
} else if (connector instanceof WalletLink) {
return 'WalletLink'
} else {
return 'Unknown'
}
}
function Status({
connector,
hooks: { useChainId, useAccounts, useError },
}: {
connector: Connector
hooks: Web3ReactHooks
}) {
const chainId = useChainId()
const accounts = useAccounts()
const error = useError()
const connected = Boolean(chainId && accounts)
return (
{getName(connector)}
{error ? (
<>
🛑 {error.name ?? 'Error'}: {error.message}
>
) : connected ? (
<>✅ Connected>
) : (
<>⚠️ Disconnected>
)}
)
}
function ChainId({ hooks: { useChainId } }: { hooks: Web3ReactHooks }) {
const chainId = useChainId()
return Chain Id: {chainId ? {chainId} : '-'}
}
function useBalances(
provider?: ReturnType,
accounts?: string[]
): BigNumber[] | undefined {
const [balances, setBalances] = useState()
useEffect(() => {
if (provider && accounts?.length) {
let stale = false
void Promise.all(accounts.map((account) => provider.getBalance(account))).then((balances) => {
if (!stale) {
setBalances(balances)
}
})
return () => {
stale = true
setBalances(undefined)
}
}
}, [provider, accounts])
return balances
}
function Accounts({ hooks: { useAccounts, useProvider, useENSNames } }: { hooks: Web3ReactHooks }) {
const provider = useProvider()
const accounts = useAccounts()
const ENSNames = useENSNames(provider)
const balances = useBalances(provider, accounts)
return (
Accounts:
{accounts === undefined
? ' -'
: accounts.length === 0
? ' None'
: accounts?.map((account, i) => (
{ENSNames?.[i] ?? account}
{balances?.[i] ? ` (Ξ${formatEther(balances[i])})` : null}
))}
)
}
function MagicInput({ email, setEmail }: { email: string; setEmail?: (email: string) => void }) {
return (
)
}
function MagicConnect({
connector,
hooks: { useIsActivating, useError, useIsActive },
}: {
connector: Magic
hooks: Web3ReactHooks
}) {
const isActivating = useIsActivating()
const error = useError()
const active = useIsActive()
const [email, setEmail] = useState()
if (error) {
return (
<>
>
)
} else if (isActivating || active) {
return (
<>
>
)
} else {
return (
<>
>
)
}
}
function MetaMaskSelect({ chainId, setChainId }: { chainId: number; setChainId?: (chainId: number) => void }) {
return (
)
}
function MetaMaskConnect({
connector,
hooks: { useChainId, useIsActivating, useError, useIsActive },
}: {
connector: MetaMask
hooks: Web3ReactHooks
}) {
const currentChainId = useChainId()
const isActivating = useIsActivating()
const error = useError()
const active = useIsActive()
const [desiredChainId, setDesiredChainId] = useState(-1)
const setChainId = useCallback(
(chainId: number) => {
setDesiredChainId(chainId)
if (chainId !== -1 && chainId !== currentChainId) {
return connector.activate(getAddChainParameters(chainId))
}
},
[setDesiredChainId, currentChainId, connector]
)
if (error) {
return (
<>
>
)
} else if (active) {
return (
<>
>
)
} else {
return (
<>
>
)
}
}
function NetworkSelect({ chainId, setChainId }: { chainId: number; setChainId?: (chainId: number) => void }) {
return (
)
}
function NetworkConnect({
connector,
hooks: { useIsActivating, useChainId, useError, useIsActive },
}: {
connector: Network
hooks: Web3ReactHooks
}) {
const isActivating = useIsActivating()
const currentChainId = useChainId()
const error = useError()
const active = useIsActive()
const [desiredChainId, setDesiredChainId] = useState(1)
const setChainId = useCallback(
(chainId: number) => {
setDesiredChainId(chainId)
return connector.activate(chainId)
},
[setDesiredChainId, connector]
)
if (error) {
return (
<>
>
)
} else if (active) {
return (
<>
>
)
} else {
return (
<>
>
)
}
}
function GenericConnect({
connector,
hooks: { useIsActivating, useError, useIsActive },
}: {
connector: Connector
hooks: Web3ReactHooks
}) {
const isActivating = useIsActivating()
const error = useError()
const active = useIsActive()
if (error) {
return
} else if (active) {
return
} else {
return (
)
}
}
function Connect({ connector, hooks }: { connector: Connector; hooks: Web3ReactHooks }) {
return connector instanceof Magic ? (
) : connector instanceof MetaMask ? (
) : connector instanceof Network ? (
) : (
)
}
export default function App() {
return (
{connectors.map(([connector, hooks], i) => (
))}
)
}