The following script might help you to achieve the multi-providers case (it is written in Node.js using TypeScript and is quite lightweight):
import Web3 from 'web3';
require('dotenv').config();
const infuraKey = process.env.INFURA_KEY;
// We assign a default web3 provider
let web3 = new Web3(new Web3.providers.HttpProvider('http://127.0.0.1:7545'));
// List of our web3 providers
const providers = [
new Web3(new Web3.providers.HttpProvider('http://127.0.0.1:7545')),
new Web3(new
Web3.providers.HttpProvider(`https://ropsten.infura.io/v3/${infuraKey}`)),
];
// Selects the first web3 provider available from our list
const providerSelector = async () => {
let selectedProvider = null;
for (let i = 0; i < providers.length; i++) {
await providers[i].eth.getBlockNumber()
.then(() => { selectedProvider = providers[i] })
.catch(() => { console.log(`Provider ${i} not available`) });
if (selectedProvider) {
web3 = selectedProvider;
return true;
};
};
return false;
};
const main = async () => {
// Example (here we can put any query, transaction, etc)
web3.eth.getBlockNumber()
.then(() => {
// Do our stuff
})
.catch(async (err) => {
// If current provider is not available, try another one from the list
const res = JSON.stringify(err, Object.getOwnPropertyNames(err));
if (res.includes('Invalid JSON RPC response'))
(await providerSelector()) ? main() : console.log('No providers available');
});
};
main();
So we have basically providers
, which is our list of web3 providers to that we will use depending on their availability.
Whenever we launch a transaction or do any interaction with web3, we need to catch the error exception and in case it is an Invalid JSON RPC response
, then we will try finding a new provider and re-try the same function recursively.
In case that no provider is available, the function will just finish because the providerSelector
function will return false.