Wallets that support multiple accounts and multiple blockchains, like MetaMask, make it very easy for a user to change active account and active blockchain. A web3 frontend should react immediately to these changes.
NOTE: This series of articles use TypeChain to make strongly-typed calls to Ethereum. Please check its documentation and discussion board to learn how to set it up. It’s also assumed some knowledge of React Query.
On the previous posts the contract address was added to the
queryKey so that
useQuery uses a different cache for each instance of the contract.
A contract can be deployed on multiple blockchains, like Ethereum, Goerli, Polygon, etc. It can have the same address in each of the blockchains but these would still be different instances. This means that the blockchain identifier must also be part of the
Each blockchain has a unique identifier. This is commonly called the chainId. You can find all the chainIds listed at https://chainlist.org/.
In TypeChain all the contracts derive from ether’s
BaseContract. This exposes the
address property that we’ve been using. The
chainId can be retrieved using the
getChainId() method found in the
signer property. This is an async method that returns a
React does not support asynchronous methods directly so we need the following source code using an
useEffect and an
useEffect is called every time
contract changes. It calls an asynchronous method that calls
chainId was added to the
useMemo so that it updates the
queryKey when the asynchronous method finishes setting the
Putting it all together looks like this:
This custom hook seems a bit complex but it adds the following to all the advantages already listed in part 1 of the series:
- Caches different values depending on the contract
- Updates are triggered by events emitted by the contract.
- Use of optimistic updates.
- Allow external reset of cache by exposing the
Using hooks like this one results in reactive applications where the user doesn’t have to refresh the page or, wait for replies to unnecessary and potentially slow calls.
It’s possible to expand this pattern to other smart contract methods. Just be careful to add all the query properties to the
queryKey and, subscribe to all the relevant smart contract events to invalidate the query.