A wrapper to use SWR with Ethereum
const { data: balance } = useEthSWR(['getBalance', 'latest'])
You can use all the methods provided by a Web3Provider from Ether.js
const { data: balance } = useEthSWR([
'0x6b175474e89094c44da98b954eedeac495271d0f', // DAI contract
'balanceOf', // Method
'0x5d3a536e4d6dbd6114cc1ead35777bab948e3643' // holder
])
You can use all the methods provided by a contract as long as you have provided the ABI associated to the smart contract
Subscribe to a topic refresh automatically the underline data once it's dispatched
const { data: balance, mutate } = useEthSWR([address, 'balanceOf', account], {
subscribe: [
// A filter from anyone to me
{
name: 'Transfer',
topics: [null, account]
},
// A filter from me to anyone
{
name: 'Transfer',
topics: [account, null]
}
]
})
return (
<div>
{parseFloat(formatUnits(balance, decimals)).toPrecision(4)} {symbol}
</div>
)
Subscribe to a topic providing a callback allows to use an optimistic update
const { data: balance, mutate } = useEthSWR([address, 'balanceOf', account], {
subscribe: [
// A filter from anyone to me
{
name: 'Transfer',
topics: [null, account],
on: (
data: BigNumber,
fromAddress: string,
toAddress: string,
amount: BigNumber,
event: any
) => {
console.log('receive', { event })
const update = data.add(amount)
mutate(update, false) // optimistic update skip re-fetch
}
},
// A filter from me to anyone
{
name: 'Transfer',
topics: [account, null],
on: (
data: BigNumber,
fromAddress: string,
toAddress: string,
amount: BigNumber,
event: any
) => {
console.log('send', { event })
const update = data.sub(amount)
mutate(update, false) // optimistic update skip re-fetch
}
}
]
})
return (
<div>
{parseFloat(formatUnits(balance, decimals)).toPrecision(4)} {symbol}
</div>
)
You can use EthSWRConfig
to have a global fetcher capable of retrieving basic Ethereum information (e.g. block, getBalance)
or directly interact with a smart contract mapped to its ABI.
import React from 'react'
import { Web3ReactProvider, useWeb3React } from '@web3-react/core'
import { Web3Provider } from '@ethersproject/providers'
import { InjectedConnector } from '@web3-react/injected-connector'
import { BigNumber } from 'ethers'
import { formatEther, formatUnits } from '@ethersproject/units'
import useEthSWR, { EthSWRConfig } from 'ether-swr'
import ERC20ABI from './ERC20.abi.json'
const ABIs = [
['0x6b175474e89094c44da98b954eedeac495271d0f', ERC20ABI]
]
const EthBalance = () => {
const { account } = useWeb3React<Web3Provider>()
const { data: balance } = useEthSWR(['getBalance', account, 'latest'])
if (!balance) {
return <div>...</div>
}
return <div>{parseFloat(formatEther(balance)).toPrecision(4)} Ξ</div>
}
const TokenBalance = ({ symbol, address, decimals }: {
symbol: string
address: string
decimals: number
}) => {
const { account } = useWeb3React<Web3Provider>()
const { data: balance } = useEthSWR([address, 'balanceOf', account])
if (!balance) {
return <div>...</div>
}
return (
<div>
{parseFloat(formatUnits(balance, decimals)).toPrecision(4)} {symbol}
</div>
)
}
export const TokenList = ({ chainId }: { chainId: number }) => {
return (
<>
{['0x6b175474e89094c44da98b954eedeac495271d0f'].map(token => (
<TokenBalance key={token.address} {...token} />
))}
</>
)
}
export const Wallet = () => {
const { chainId, account, library, activate, active } = useWeb3React<Web3Provider>()
const onClick = () => {
activate(injectedConnector)
}
return (
<div>
<div>ChainId: {chainId}</div>
<div>Account: {shorter(account)}</div>
{active ? (
<span role="img" aria-label="active">
✅{' '}
</span>
) : (
<button type="button" onClick={onClick}>
Connect
</button>
)}
{active && chainId && (
<EthSWRConfig
value={{ provider: library, ABIs: new Map(ABIs) }}
>
<EthBalance />
<TokenList chainId={chainId} />
</EthSWRConfig>
)}
</div>
)
}
A minimal example with an event is available here
Licensed under MIT.