web icon indicating copy to clipboard operation
web copied to clipboard

Spike: Use wagmi hooks

Open gomesalexandre opened this issue 2 years ago • 0 comments

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 with useEnsName. 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 with useContract()

  • useCurrentBlockNumber - could be replaced with useBlockNumber. It is consumed exclusively by react hooks.

https://github.com/shapeshift/web/blob/87d8c1dbf56dcfddfa79977bf83f2792f644dc88/src/plugins/foxPage/hooks/useCurrentBlockNumber.ts#L9

https://github.com/shapeshift/web/blob/87d8c1dbf56dcfddfa79977bf83f2792f644dc88/src/plugins/foxPage/utils.ts#L16-L19

  • useEvm - we might or might not want to replace wallet.ethGetChainId() calls with useNetwork. That's technically not following our wallet abstraction, but I believe in this case, it is fine to let web handle this concern, as all ethGetchainId 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 with useSwitchNetwork(). 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 with contractInstance.totalSupply() calls - both could be replaced with useToken as we're effectively just calling the standard EIP-20 totalSupply() 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

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 exposed erc20ABI from wagmi
  • https://etherscan.io hardcoded base URLs could be replaced with etherscanBlockExplorers.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 of useContractRead() and offer caching options, so we might want to use these instead in most places.
  • All wagmi contract-interacting methods accept a cacheTime and staleTime 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

gomesalexandre avatar Sep 09 '22 14:09 gomesalexandre