0

I have written the script below which creates multiple WebSocket connections with a smart contract to listen to events. it's working fine but I feel this is not an optimized solution and probably this could be done in a better way.

const main = async (PAIR_NAME, PAIR_ADDRESS_UNISWAP, PAIR_ADDRESS_SUSHISWAP) => {
    const PairContractHTTPUniswap = new Blockchain.web3http.eth.Contract(
        UniswapV2Pair.abi,
        PAIR_ADDRESS_UNISWAP
    );
    const PairContractWSSUniswap = new Blockchain.web3ws.eth.Contract(
        UniswapV2Pair.abi,
        PAIR_ADDRESS_UNISWAP
    );
    const PairContractHTTPSushiswap = new Blockchain.web3http.eth.Contract(
        UniswapV2Pair.abi,
        PAIR_ADDRESS_SUSHISWAP
    );
    const PairContractWSSSushiswap = new Blockchain.web3ws.eth.Contract(
        UniswapV2Pair.abi,
        PAIR_ADDRESS_SUSHISWAP
    );

    var Price_Uniswap = await getReserves(PairContractHTTPUniswap);
    var Price_Sushiswap = await getReserves(PairContractHTTPSushiswap);

    // subscribe to Sync event of Pair
    PairContractWSSUniswap.events.Sync({}).on("data", (data) => {
        Price_Uniswap = (Big(data.returnValues.reserve0)).div(Big(data.returnValues.reserve1));
        priceDifference(Price_Uniswap, Price_Sushiswap, PAIR_NAME);
    });
    PairContractWSSSushiswap.events.Sync({}).on("data", (data) => {
        Price_Sushiswap = (Big(data.returnValues.reserve0)).div(Big(data.returnValues.reserve1));
        priceDifference(Price_Uniswap, Price_Sushiswap, PAIR_NAME);
    });
};

for (let i = 0; i < pairsArray.length; i++){
        main(pairsArray[i].tokenPair, pairsArray[i].addressUniswap, pairsArray[i].addressSushiswap);
    }

In the end, I instantiate the main function multiple times for each pair from a pair array, in a for-loop. I think this way of solving is brute force and there is a better way of doing this.

Any suggestions/opinions would be really appreciated.

1 Answers1

0

Just to clear up the terms: You're opening a websocket connection to the WSS node provider - not to the smart contracts. But yes, your JS snippet subscribes to multiple channels (one for each contract) within this one connection (to the node provider).

You can collect event logs from multiple contracts through just one WSS channel using the web3.eth.subscribe("logs") function (docs), passing it the list of contract addresses as a param. Example:

const options = {
    // list of contract addresses that you want to subscribe to their event logs
    address: ["0x123", "0x456"]
};
web3.eth.subscribe("logs", options, (err, data) => {
    console.log(data);
});

But it has a drawback - it doesn't decode the event log data for you. So your code will need to find the expected data types based on the event signature (returned in data.topics[0]). Once you know which event log is emitted based on the topics[0] event signature (real-life example value in this answer), you can use the decodeLog() function (docs) to get the decoded values.

Petr Hejda
  • 40,554
  • 8
  • 72
  • 100
  • First of all, thank you so much for giving an interesting solution and sorry for replying so late. I implemented this way of subscribing but I do need to perform calculations on the results of specific addresses from the address array. Like, the address array might contain dai/Weth address of Uniswap and Sushiswap and then address of Sushi/Weth of Uniswap and Sushiswap. addressarray = [dai/Weth-Uniswap, dai/Weth-Sushiswap, Sushi/Weth-Uniswap, Sushi/Weth-Sushiswap]. now, I need to perform calculations on each corresponding pair of addresses, ie. indexed 0, 1 and 2, 3. Any Suggestions? – Lalit Tanna Jan 07 '22 at 11:18