oceanprotocol / market

🧜‍♀️ THE Data Market
https://market.oceanprotocol.com
Apache License 2.0
187 stars 292 forks source link

WalletConnect v2, wallets & web3 #1828

Closed kremalicious closed 1 year ago

kremalicious commented 1 year ago

When starting market project there were only 2 libraries to connect a wallet to a dApp so we had to write logic to deal with wallet connections on our own, pretty much consolidated in @context/web3. Now that we are forced to migrate to WalletConnect v2, we should revisit and take decision on how we want app to connect to wallets and work with web3 in the future.

Problem

WalletConnect v1 has reached end-of-life and will start to be sunsetted for dApps beginning January 1, 2023 and will stop working completely on March 30, 2023.

The v2 version comes with some architectural changes and if we do not want to run our own WalletConnect relayer, we have to use their cloud offering.

The React version of Web3Modal enforces usage of wagmi & ethers.js, but we use our own custom hooks and web3.js, the latter being enforced by ocean.js.

Additionally, we are constantly struggling to decide when to use which web3 connection, user wallet or fallback (what we call "dummy web3"), while all industry tools do that automatically. And on top of that we constantly run into bundling issues with some minor new web3.js version, where currently we had to switch deployment tools to deal with that.

Possible Solutions

1. Migrate to Web3Modal standalone version

Should be pretty straight forward where we continue handling everything manually, in our @context/Web3 context provider. This then needs to be extended so we never have to decide on web3 or "dummy web3", so we need some fallback logic in case user wallet web3 connection can't be established.

No new dependencies will be introduced, except for kicking out old walletconnect stuff, and use their new dependencies. Could not find some stuff we use like IProviderInfo but might be all doable still.

2. Migrate to Web3Modal React version

This forces use of wagmi and ethers, both of which are excellent choices as this is where the industry moved to in the last 2 years. But ocean.js enforces usage of web3.js for all projects which use ocean.js so we are forced to bundle 2 different web3 libraries in final app.

What we do in @context/web3 is then redundant as wagmi does this all out of the box. But we should get away with not increasing bundle size a lot if tree shaking and transpiling works properly in the end.

3. Migrate to Web3Modal React version, wagmi, ethers, and kill @context/web3, web3.js

All we do in @context/web3 and our useWeb3() hook can be done with wagmi out of the box. So we can remove all our custom web3 handling and migrate all useWeb3() calls to wagmi's hooks. Then setup Web3Modal React version from scratch. This then also magically solves the "dummy web3" issue and we don't have to deal with this ever again.

Remaining things from @context/web3 can then be moved to another context provider, like MarketMetadata:

All this at least requires ocean.js to remove web3.js as peer dependency. Expecting no heavy incompatibilities when market users ethers.js and ocean.js uses web3.js, but some issues regarding different number treatments might pop up.

4. Migrate to RainbowKit

If we decide to run with wagmi & ethers we could ultimately migrate to other wallet libraries which use the same underlying tools, like RainbowKit. Provides best user experience of all the wallet libraries, but might be a bit rudimentary when it comes to support for all the different wallets so would need to be explored.

Would include same path as no. 3 where we can do everything needed to be done with web3 can be accomplished with wagmi + ethers.js.


Personally would prefer no. 3 as it's the most future proof where we are finally able to outsource everything around wallet connection logic to external libraries too. And ethers.js is better than web3.js in almost every way.

Any possibility I missed?

jamiehewitt15 commented 1 year ago

3 sounds like a good plan. I particularly like the idea of using something like RainbowKit to allow users to user more wallets. There is another similar option from blocknative: https://onboard.blocknative.com/

kremalicious commented 1 year ago

Here's what I learned after 3 prototypes:

Option 1 & 2 won't work out as expected as the web3modal-standalone version does not include support for MetaMask. So with that we get a modal, but there's no option to use MetaMask. If we want to support MetaMask, this requires us to create our own modal, and then handle MetaMask & WalletConnect individually within our own useWeb3() context provider. This would mean replicating everything Web3Modal did for us so far, like saving everything in localStorage for reconnection, watching network & account changes for both connections and much more. Cause web3modal-standalone version will only do this for WalletConnect connections.

This is prototyped in feature/walletconnect-v2-standalone branch, with adding MetaMask support pending.

Option 3 works beautifully, until we add ocean.js to the mix, which requires the web3.js object to be passed around. Which we can't get with ethers.js. The only way forward here would be to refactor ocean.js to use ethers.js.

This is prototyped in the feature/wagmi branch.

We really should not deal with handling individual wallet connections in our frontend, and at same time should not force all our users to use a library none of the popular tools out there are actually using. So migrating ocean.js to ethers.js still would be best solution I guess

alexcos20 commented 1 year ago

I will start working on a Ocean.js branch using ethers.js instead of web3.js

LoznianuAnamaria commented 1 year ago

Done and merged in ocean.js v3