web3.js Providers Guide
Connecting to a chain happens through a provider. You can pass the provider to the constructor as in the following example:
import { Web3 } from `web3`
const web3 = new Web3(/* PROVIDER*/);
// calling any method that interact with the network would involve using the early passed provider.
await web3.eth.sendTransaction({
from,
to,
value,
});
The created Web3 instance will use the passed provider to interact with the blockchain network. This interaction happen when sending a request and receiving the response, and when possibly listen to provider events (if the provider support this).
Providers Types
Actually, the provider could be any of the following:
- An instance of HttpProvider
- An instance of WebSocketProvider
- An instance of IpcProvider
- A string containing string url for
http
/https
,ws
/wss
, oripc
protocol. And when a string is passed, an instance of the compatible class above will be created accordingly. ex. WebSocketProvider instance will be created for string containingws
orws
. And you access this instance by callingweb3.provider
to read the provider and possibly register an event listener. - Any provider object that adhere to EIP-1193. And it has been tested with Ganache provider, Hardhat provider, and Incubed (IN3) as a provider.
For both WebSocketProvider and IpcProvider the user can listen to emitted events. More on this is at Providers Events Listening.
tip
The passed provider can be either type string
or one of the SupportedProviders
. And if it is passed as a string, then internally the compatible provider object will be created and used.
Providers Priorities
There are multiple ways to set the provider.
web3.setProvider(myProvider);
web3.eth.setProvider(myProvider);
web3.Contract.setProvider(myProvider);
contractInstance.setProvider(myProvider);
The key rule for setting provider is as follows:
- Any provider set on the higher level will be applied to all lower levels. e.g. Any provider set using
web3.setProvider
will also be applied toweb3.eth
object. - For contracts
web3.Contract.setProvider
can be used to set provider for all instances of contracts created byweb3.eth.Contract
.
Examples
Local Geth Node
const Web3 = require('web3');
const web3 = new Web3('http://localhost:8545');
// or
const web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:8545'));
// change provider
web3.setProvider('ws://localhost:8546');
// or
web3.setProvider(new Web3.providers.WebsocketProvider('ws://localhost:8546'));
// Using the IPC provider in node.js
const net = require('net');
const web3 = new Web3('/Users/myuser/Library/Ethereum/geth.ipc', net); // mac os path
// or
const web3 = new Web3(
new Web3.providers.IpcProvider('/Users/myuser/Library/Ethereum/geth.ipc', net),
); // mac os path
// on windows the path is: "\\\\.\\pipe\\geth.ipc"
// on linux the path is: "/users/myuser/.ethereum/geth.ipc"
Remote Node Provider
// Using a remote node provider, like Alchemy (https://www.alchemyapi.io/supernode), is simple.
const Web3 = require('web3');
const web3 = new Web3('https://eth-mainnet.alchemyapi.io/v2/your-api-key');
Injected providers
As stated above, the injected provider should be in compliance with EIP-1193. And it is tested with Ganache provider, Hardhat provider, and Incubed (IN3) as a provider.
The web3.js 4.x Provider specifications are defined in web3 base provider for Injected Providers.
const Web3 = require('web3');
// Using an EIP1193 provider like MetaMask can be injected
if (window.ethereum) {
// Check if ethereum object exists
await window.ethereum.request();
window.web3 = new Web3(window.ethereum); // inject provider
}
Provider Options
There are differences in the objects that could be passed in the Provider constructors.
HttpProvider
The options is of type HttpProviderOptions
, which is an object with a single key named providerOptions
and its value is an object of type RequestInit
.
Regarding RequestInit
see microsoft's github.
For example:
const httpOptions = {
providerOptions: {
body: undefined,
cache: 'force-cache',
credentials: 'same-origin',
headers: {
'Content-Type': 'application/json',
},
integrity: 'foo',
keepalive: true,
method: 'GET',
mode: 'same-origin',
redirect: 'error',
referrer: 'foo',
referrerPolicy: 'same-origin',
signal: undefined,
window: undefined,
} as RequestInit,
};
WebSocketProvider
The options object is of type ClientRequestArgs
or of ClientOptions
. See here for ClientRequestArgs
and here for ClientOptions
.
The second option parameter can be given regarding reconnecting. And here is its type:
type ReconnectOptions = {
autoReconnect: boolean;
delay: number;
maxAttempts: number;
};
info
Here is how to catch the error if max attempts reached when the auto reconnecting:
provider.on('error', errorMessage => {
if (errorMessage.startsWith('Maximum number of reconnect attempts reached!')) {
// the `errorMessage` will be `Maximum number of reconnect attempts reached! (${maxAttempts})`
// the `maxAttempts` is equal to the provided value by the user or the default `5`.
}
});
Options example
Below is an example for the passed options:
let clientOptions: ClientOptions = {
// Useful for credentialed urls, e.g: ws://username:password@localhost:8546
headers: {
authorization: 'Basic username:password',
},
maxPayload: 100000000,
};
const reconnectOptions: ReconnectOptions = {
autoReconnect: true,
delay: 5000,
maxAttempts: 5,
};
Error message for reconnect attempts
note
This section applies for both IpcProvider
and WebSocketProvider
.
The error message, for the max reconnect attempts, will contain the value of the variable maxAttempts
as follows:
`Maximum number of reconnect attempts reached! (${maxAttempts})`
And here is how to catch the error, if max attempts reached when there is auto reconnecting:
provider.on('error', error => {
if (error.message.startsWith('Maximum number of reconnect attempts reached!')) {
// the `error.message` will be `Maximum number of reconnect attempts reached! (${maxAttempts})`
// the `maxAttempts` is equal to the provided value by the user, or the default value `5`.
}
});