Web3 Provider Library

Greetings!

We’ve been thinking how we can improve Ethereum developer experience and one of the pain points we came across is interaction with Web3 providers.
We would love to receive feedback on that proposal from the community, especially from @mortimr, @asselstine, @ianbrtt, @scammi, @paulinablaszk, @rstormsf, @obernardovieira!

Web3 Provider API

this product is for Ethereum Developers
who need an easy and reliable way to manage Web3 providers
this implementation hides various providers behind common API
that provides one line access to Web3 Provider API
unlike web3-react, embark.js
this solution doesn’t force you to use other libs

Why?

The current state of Web3 Providers is a wild combination of various EIPS (1474, 1193, 1102), libraries (web3.js, ethers.js, metamask, truffle), clients (geth, parity, ganache) and transport layers (HTTP, web sockets, IPC). Given the possibility of almost any combination of the mentioned factors, it is absolutely impossible to predict the outcome for a particular project. Some combinations wouldn’t even run but rather just throw a straight error on a start.

What do Ethereum application developers need from Web3 provider?
Surprisingly most Ethereum developers have quite common needs:

  • Get data from Ethereum blockchain
  • Send transactions
  • React on network changed, account change and other events
  • There are other niche requirements but they can be handled given the first three satisfied and working instance of Web3 library is provided.

Challenges

Does current provider support events (accountsChanged, networkChanged)?
It depends on a library, for example, web3.js@1.0.0-beta.37 which is used a lot doesn’t support these events. Some clients don’t support WebSockets. HttpProvider will never support it due to the nature of HTTP and considered depreciated, yet despite all of this it is the most widely mentioned and popular Web3 provider. In short, it is impossible to answer precisely and the most likely answer right now is no.

Can current provider sign and send transaction?
Is it Infura? Then no. Is it Metamask? If it is unlocked and the user will sign then yes. Is it Geth? If accounts unlocked then yes. From a JS layer, it is impossible to say will the current provider sign a transaction. Even more, there is no guarantee that the next transaction will be signed even if previous was successful. Geth can be locked down by timeout for example.

Are we connected to the Ethereum right now?
Not only some providers like HttpProvider not capable of notifying connectivity loss but in many cases they can die silent – forceful termination of a node, disabling Metamask extension. It is crucial for reliable and delightful developer experience to notify on connection loss as soon as possible.

Solution

Given current situation in tech stack surrounding Web3 providers, we have to provide the solution to maximize reliability and consistency while minimizing dependency on particular implementations.

interface Web3Context {
  connected: boolean,
  accounts: string[],
  networkId: number,
  lib: any,
  onAccountsChanged(callback: (accounts: string[]) => void);
  onNetworkChanged(callback: (networkId: number) => void);
  onConnectionChanged(callback: (connected: boolean) => void);
}

connected
Returns true if connected to Ethereum node

accounts
Returns a list of accounts.

networkId
Returns a network id of a currently connected network.

lib
Returns instance of web3.js set up with the current provider.

onAccountsChanged
Fires every time accounts change.

onNetworkChanged
Fires every time a network change.

onConnectionChanged
Fires if a connection is established or lost.

Implementation Details

Events onAccountsChanged and onNetworkChanged picked because they satisfy all the requirements with minimal API and compliant with EIP 1193.
Behind the scene, Web3Context wouldn’t rely on EIP 1193 to receive such events from a Web3 provider because it might be not be available and the only Web3 provider to support it fully seems to be Metamask. Instead of that Web3Context will use a 100 milliseconds poll to query for much more reliable eth_accounts and net_version functions from EIP 1474 and update the state, fire events based on that. The approach also resolves the loss of a connection issue.
Web3Context would also call ethereum.enable if it detects window.ethereum instance presence according to the EIP 1102.

Getting Web3Context

function getInjectedWeb3(): Web3Context
function getNetworkWeb3(connection: string): Web3Context

You either get Web3Context from an injected provider like Metamask or you are connected using a provider like Infura. For a start, we’ll leverage web3.js to create providers based on a connection string but if needed we can create our own providers or wrap existing.

What next?

Create helper functions for React to injected and manage our Web3Context
Update ZepKit with Web3Context
GSN network support

6 Likes

Hello @ylv-io,

Great. I’ve been feeling that same pain for a while. Two questions:

  1. Is it just for the development phase?
  2. Do we need metamask?
2 Likes

Hey @obernardovieira!

  1. No, it is for production as well. We want to provide abstraction over web3 providers so developers do not need to worry about managing providers themselves.
  2. No. It will be able to connect via any web3 provider metamask, ganache, infura. It is provider agnostic.
4 Likes

Oh, now I fully understood.
Great, that’s awesome.
But I just found one interesting thing today web3-connector
Is it somehow similar? Also, it uses https://github.com/NoahZinsmeister/web3-react.
I’m just trying to make sure I’m not misunderstanding something.

2 Likes

I fully support this and been thinking about it, even though I used web3.js I never encountered any issues, that means that I don’t really have that much experience on Web3.js , so I would love to see the progress on this and start using it now that I know it will be much better :slight_smile:

2 Likes

Hey @obernardovieira!
It is similar to web3-react in the goals but we don’t want to be opinionated about frontend because people may use Vue/Angular/whatever when web3-react is only for react.
Yet we are planning to make additional helpers for the most popular frameworks like react so the core module will be frontend agnostic but we’ll have helpers for top frameworks as well.
Hope it makes sense. If you have more questions feel free to ask.

2 Likes

It is not issues of web3.js or any other library in particular. It is the whole situation. For example user may disable metamask plugin in a browser, and your application will not receive a notification. Another example Geth node would forcefully terminate, again there will be no notification so your app would have stale UI.
Does it make sense?

2 Likes

Great initiative :slight_smile: I really like the idea that the library won’t be connected to any frontend framework. It is important especially for people that work with different frameworks. Can’t wait to try it!

4 Likes

I like this effort, as it would be valuable to make web3.js even more event-driven. Previously we’ve managed the account and network using Redux Saga polling. Ideally the web3.js library itself could be made more event-driven, but if this needs to start as an additional layer, then so be it.

One bit of feedback I would offer is that it would be ideal for the developer to be able to trigger the window.ethereum.enable(). In many instances, we don’t want to bug the user about connecting to the app until it’s absolutely appropriate. Principle: prove the value before the ask :slight_smile:

As for us, we’ve been very happy so far using Ethers.js so we aren’t experiencing the web3.js paint point anymore :wink:

2 Likes

Hey @asselstine. Thanks for contributing!
I agree that eventually web3 libraries would be more event driven and probably will handle all the current issues.

One bit of feedback I would offer is that it would be ideal for the developer to be able to trigger the window.ethereum.enable()

Love it :heart: Everytime I go to the website and pushes metamask into my face I instantly press reject!
Regarding ether.js. Does it handle all the events itself? Like node losing connection? Metamask being disabled?

1 Like