web
web copied to clipboard
Spike: Use wagmi hooks
Overview
As we start to have more direct chain-interacting logic around the codebase (as opposed to using chain-adapters
to build/sign/broadcast Txs), there is currently a lot of wheel reinvention happening, namely:
- ENS address resolution
- FOX/ETH featureset
- Fox Page featureset
Additionally to reinventing the wheel, this brings some performance issues, the biggest concern being overfetching.
-
new Contract()
makes an Infura request on every instantiation - Contract data isn't cached when it actually could
- ENS resolution response isn't cached when it actually could
- EIP-1193 provider instantiation
While using libraries like Ethers.js
and @ensdomains/ensjs
for contract instantiation, along with our singletons does the heavy lifting, and switching to RTK queries will alleviate most of these issues, I believe there is at least value in not reinventing the wheel and relying on a battle-tested, maintained library which handles these concerns so we can focus on business logic.
wagmi does precisely that, with a collection of react hooks handling these concerns.
This issues serves as a spike for this.
References and additional details
-
lib/address/ens
- could be replaced withuseEnsName
. It is used exclusively in react components. Note that given our flow and the fact we already know the address when looking up an ENS name,useEnsAddress
for resolution shouldn't be needed.
https://github.com/shapeshift/web/blob/04c303c7db802f188269f01521fdf6d657d6836e/src/lib/address/ens.ts#L27
-
new Contract()
(@ethersproject/contract
instantiation) - these could be replaced withuseContract()
-
useCurrentBlockNumber
- could be replaced withuseBlockNumber
. It is consumed exclusively by react hooks.
https://github.com/shapeshift/web/blob/87d8c1dbf56dcfddfa79977bf83f2792f644dc88/src/plugins/foxPage/hooks/useCurrentBlockNumber.ts#L9
-
getEthersProvider
singleton - could be replaced withuseProvider
or exposed staticStaticJsonRpcProvider
https://github.com/shapeshift/web/blob/87d8c1dbf56dcfddfa79977bf83f2792f644dc88/src/plugins/foxPage/utils.ts#L16-L19
-
useEvm
- we might or might not want to replacewallet.ethGetChainId()
calls withuseNetwork
. That's technically not following our wallet abstraction, but I believe in this case, it is fine to let web handle this concern, as allethGetchainId
is doing is making the exact same call.
https://github.com/shapeshift/web/blob/d665d1030c9483e915a4c603fa997b67adf8cbb4/src/hooks/useEvm/useEvm.ts#L29
-
wallet.ethSwitchChain()
- similarly, this only calls the underlying Ethereum JSON-RPC method, and could be replaced withuseSwitchNetwork()
. Same thing, this doesn't conform to our wallet abstraction, but letting web handle this instead of wallet might be a better choice. Interestingly:
Some wallet apps do not support programmatic network switching and switchNetwork will be undefined.
This might also be able our supportsEthSwitchChain
concerns.
https://github.com/shapeshift/web/blob/d665d1030c9483e915a4c603fa997b67adf8cbb4/src/components/Layout/Header/NavBar/ChainMenu.tsx#L52
-
getTotalLpSupply
and other places withcontractInstance.totalSupply()
calls - both could be replaced withuseToken
as we're effectively just calling the standard EIP-20totalSupply()
public view
method
https://github.com/shapeshift/web/blob/87d8c1dbf56dcfddfa79977bf83f2792f644dc88/src/plugins/foxPage/utils.ts#L95-L98 https://github.com/shapeshift/web/blob/f079c8d685653403d979bcb928c88f2d173f71de/src/features/defi/providers/fox-eth-lp/hooks/useFoxEthLiquidityPool.ts#L300
-
contractInstance.balanceOf
- could be replaced withuseBalance
as we're effectively just calling the standard EIP-20balanceOf()
public view
method, which is also what this hook uses under the hood for ERC-20 balances
https://github.com/shapeshift/web/blob/f079c8d685653403d979bcb928c88f2d173f71de/src/features/defi/providers/fox-eth-lp/hooks/useFoxEthLiquidityPool.ts#L299
Additionally:
-
erc20Abi.json
could be removed in favor of the exposederc20ABI
from wagmi -
https://etherscan.io
hardcoded base URLs could be replaced withetherscanBlockExplorers.mainnet.url
-
jsonRpcProvider
wagmi config can be used to set-up wagmi's JSON-RPC providers in a single source of truth -
https://wagmi.sh/docs/hooks/useContractRead
/https://wagmi.sh/docs/hooks/useContractReads
can be used to read one/many contract/s read-only methods. Note that these are recommended to be used in-place ofuseContractRead()
and offer caching options, so we might want to use these instead in most places. - All wagmi contract-interacting methods accept a
cacheTime
andstaleTime
options, which consistently default to zero. There are many places where we want to use cached data instead of getting fresh data every call, so this should mitigate a lot of the overfetching. This is passed to the underlying react-query package wagmi uses under the hook, read more here: https://tanstack.com/query/v4/docs/guides/caching
Acceptance Criteria
- We know what can be replaced with wagmi hooks
Need By Date
No response
Screenshots/Mockups
No response
Estimated effort
No response