3

I was looking into good usage patterns of @web3-react/core, specifically was looking at Uniswap's V3 code among other places...

Examples here:

https://github.com/Uniswap/interface/blob/main/src/index.tsx#L53-L63

https://github.com/Uniswap/interface/blob/main/src/utils/getLibrary.ts

https://github.com/Uniswap/interface/search?q=useWeb3React

This is one of the cleanest usages of @web3-react/core I could find, and definitely not trying to call out anyone's code. :-)

However there seems to be a 'code smell' here and was just wondering how others have worked around it.

In the example code linked above the use of ethers providers is not abstracted away via typing.

Ideally I'd like a getLibrary.ts file that is the single point of the codebase that knows whether I'm using web3.js or ethers.js. This way, if I want to switch libraries, I only have to change the code in one single place.

However, the way it is used in every example I've seen is that wherever useWeb3React is imported and used, the provider library most also be imported for correct typing purposes. Eg:

import { Web3Provider } from '@ethersproject/providers'
import { useWeb3React } from '@web3-react/core'

export function useActiveWeb3React() {
  const context = useWeb3React<Web3Provider>()
  ...
}

I'm not a TypeScript guru, but it seems like in the getLibrary.ts code a typed getLibrary(): ProviderType could be exported in addition to the action type ProviderType being exported and in this way, all knowledge of the underlying web3/ethers library could be kept in a single file and if this were ever to change, only a single file (namely getLibrary.ts) would need to be updated.

Was thinking the getLibrary.ts code could look something like:

import { Web3Provider } from '@ethersproject/providers'
import type { Web3Provider as ProviderType } from '@ethersproject/providers'

export function getLibrary(provider: any): ProviderType {
   ...
}

export type ProviderType;

Then both getLibrary and ProviderType could be imported wherever typing is needed and details regarding the underlying provider could be well-encapsulated in a single TS file.

Has anyone been able to write similar code to this?

My code example above doesn't work and I havent' figured out how to get TS to do this correctly.

Thanks!

1 Answer 1

0

This seems to work well and contains everything regarding if I'm using web3 or ethers in a single file, reducing the need to change several files if I were ever to change my @web3-react library. I created a getLibrary.ts file with the following:

import { Web3Provider } from '@ethersproject/providers';
import type { Web3Provider as ProviderType } from '@ethersproject/providers';

export function getLibrary(provider: any): ProviderType {
  const library = new Web3Provider(provider);
  library.pollingInterval = 12000;
  return library;
}

export type Provider = ProviderType;

Instead of importing the specific import { Web3Provider } from '@ethersproject/providers' throughout the codebase I can simply import from getLibrary.ts when and as needed.

Whenever I want to use a typesafe useWeb3React() call I just do the following:

import { useWeb3React } from '@web3-react/core';

import { Provider } from '../ProviderLibrary';

function myFunctionalComponent() {
  const { chainId, library, etc... } = useWeb3React<Provider>();
  ...
}

And I'm good to go. This seems like a well-encapsulated approach, but would be curious to know other's thoughts.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.