In order to search logs, for every wallet connection in the Dapp, two Web3 instances must be created, one specific for logs and the other one for Blockchain interaction. This will help a lot specific customizations for fast development, prototyping and testing.
window.web3 =awaitwindow.createWeb3(window.context.blockchainConnectionString ||window.ethereum);window.networkId =awaitwindow.web3.eth.net.getId(); window.web3ForLogs = await window.createWeb3(window.getNetworkElement("blockchainConnectionForLogString") || window.web3.currentProvider);
window.createWeb3=asyncfunctioncreateWeb3(connectionProvider) {var web3 =newwindow.Web3Browser(connectionProvider);web3.currentProvider.setMaxListeners &&window.web3.currentProvider.setMaxListeners(0);web3.eth.transactionBlockTimeout =999999999;web3.eth.transactionPollingTimeout =newDate().getTime(); web3.startBlock = parseInt((typeof connectionProvider).toLowerCase() !== 'string' && window.ethereum && window.ethereum.isMetaMask ? await window.timeoutCall(async call => call(await web3.eth.getBlockNumber())) : await web3.eth.getBlockNumber()) - 100;
return web3;};In this specific case, if the blockchainConnectionForLogString configuration parameter is set, the two Web3 instances will have different connection providers:
E.g. the normal web3 instance can be linked to Ganache or local node, while the web3ForLogs one will be linked to a Infura node for fast log searches.
In any case, the log search must be done by specific method:window.getLogs=asyncfunction(a, endOnFirstResult) {var args =JSON.parse(JSON.stringify(a));var logs = [];args.fromBlock =args.fromBlock || (window.getNetworkElement('deploySearchStart') +'');args.toBlock =args.toBlock || (awaitwindow.web3.eth.getBlockNumber() +'');var to =parseInt(args.toBlock);varfillWithWeb3Logs=asyncfunction(logs, args) {if (window.web3.currentProvider ===window.web3ForLogs.currentProvider) {return logs; }var newArgs = {};Object.entries(args).forEach(entry => newArgs[entry[0]] = entry[1]);newArgs.fromBlock =window.web3.startBlock;newArgs.toBlock ='latest';logs.push(...(awaitwindow.web3.eth.getPastLogs(newArgs)));return logs; };while (isNaN(to) ||parseInt(args.fromBlock) <= to) {var newTo =parseInt(args.fromBlock) +window.context.blockSearchSection; newTo = newTo <= to ? newTo : to;args.toBlock =isNaN(newTo) ?args.toBlock : (newTo +'');logs.push(...(awaitwindow.web3ForLogs.eth.getPastLogs(args)));if (isNaN(to) ||logs.length>0&& endOnFirstResult ===true) {returnawaitfillWithWeb3Logs(logs, args); }args.fromBlock = (parseInt(args.toBlock) +1) +''; }returnawaitfillWithWeb3Logs(logs, args);};
The window.getLogs method is a simple wrapper of the method web3.eth.getPastLogs, but it does two important things:
Makes searches using block tranches for performances reasons (e.g. Infura can give back only a pre-defined amount of results);
Uses the web3ForLogs instance and then, if necessary (e.g. different Provider), uses the normal one to completely fill the search results.