Home > Mobile >  Web3.js pair contract events.Swap not correctly subscribing to swap event
Web3.js pair contract events.Swap not correctly subscribing to swap event

Time:09-08

I am trying to run a section of (nodejs using Web3.js) code whenever a swap occurs on a given pair contract (qPair is the pair contract derived from Quickswap's router contract (Polygon blockchain) and sPair is the same pair contract derived from Sushiswap's router contract (also Polygon blockchain)) but the code doesn't work as intended when implented as a class. I have it working in one file, but when I try to create a class for crypto pairs, the code wont work.

Here is the working code:

const main = async () => {
    qPair = await getPairContract(quickswapFactoryContract, token0.address, token1.address)
    sPair = await getPairContract(sushiswapFactoryContract, token0.address, token1.address)
    


    /* The below code is listening for a swap event on the Quickswap exchange. When a swap event is
    detected, the code checks the price of the token pair on Quickswap and compares it to the price
    of the token pair on Sushiswap. If the price on Quickswap is higher than the price on Sushiswap, the
    code will execute a trade on Quickswap. If the price on Sushiswap is higher than the price on
    Quickswap, the code will execute a trade on Uniswap. */
    qPair.events.Swap({}, async () => {
        console.log("qPair activated")
         /*
          *
          * Do stuff here
          *
          */
    })

    /* The below code is listening for an event on the Sushiswap contract. When the event is detected,
    the code will check the price of the token pair and determine if there is an arbitrage
    opportunity. If there is an arbitrage opportunity, the code will execute the trade. */
    sPair.events.Swap({}, async () => {
        console.log("sPair activated")
         /*
          *
          * Do stuff here
          *
          */
    })

    console.log("Waiting for swap event...")
    
}

And here is the code that doesn't work:

const main = async () => {
    qPair1 = new cryptoPair(<same token details as before go here>)
    sPair1 = new cryptoPair(<same token details as before go here>)
    
 
    qPair1.pairContract.events.Swap({}, async () => {

          // The code here activates once (after main() reaches the bottom) and never again  

    })

    sPair1.pairContract.events.Swap({}, async () => {

          // The code here activates once (after main() reaches the bottom) and never again         

        
    })
    console.log("waiting for swap event")
} // Once the debugger reaches here, the two "async" console logs activate

The class has the same code as the "working" code but instead would just do this._pairContract = await getPairContract() and then return that variable using a getter function.

Here is the (nonworking) class code:

module.exports = class cryptoPair {
    constructor(token0Address, token0Decimals, token1Address, token1Decimals, factory) {
        this._token0Address = token0Address;
        this._token0Decimals = token0Decimals;
        this._token1Address = token1Address;
        this._token1Decimals = token1Decimals;
        this._factory = factory;    
    }
    // Setter functions
    set token0(web3Token) {
        this._token0 = web3Token;
    }
    set token1(web3Token) {
        this._token1 = web3Token;
    }
    set token0Contract(web3Contract) {
        this._token0Contract = web3Contract;
    }
    set token1Contract(web3Contract) {
        this._token1Contract = web3Contract;
    }
    // Getter functions
    get token0Address() {
        return this._token0Address;
    }
    get token1Address() {
        return this._token1Address;
    }
    get factory() {
        return this._factory;
    }
    get token0Contract() {
        return this._token0Contract;
    }
    get token1Contract() {
        return this._token1Contract;
    }
    get token0() {
        return this._token0;
    }
    get pairContract() {
        return this._pairContract;
    }
    
    // The following two functions are nearly identically defined in the "working code"
    // But instead don't use the "this.variableName" syntax
    async defineTokens(t0Address, t0Decimals, t1Address, t1Decimals) {
        try {
            this._token0Contract = new web3.eth.Contract(IERC20.abi, t0Address)
            this._token1Contract = new web3.eth.Contract(IERC20.abi, t1Address)
            const t0Symbol = await this._token0Contract.methods.symbol().call()
            const t0Name = await this._token0Contract.methods.name().call()

            this._token0 = new Token(
                ChainId.POLYGON,
                t0Address,
                t0Decimals,
                t0Symbol,
                t0Name
            )
            
            const t1Symbol = await this._token1Contract.methods.symbol().call()
            const t1Name = await this._token1Contract.methods.name().call()
            
            this._token1 = new Token(
                ChainId.POLYGON,
                t1Address,
                t1Decimals,
                t1Symbol,
                t1Name
            )
        } catch (err) {
            // For some reason, I keep getting the error "hex data is odd-length" in the 
            // class but not when this same code is outside of a class
            console.log("Token creation failed, retrying...")
            this.defineTokens(this._token0Address, this._token0Decimals, this._token1Address, this._token1Decimals)
        }   
    }

    async definePairContract() {
        this._pairAddress = await this._factory.methods.getPair(this._token0Address, this._token1Address).call();
        this._pairContract = new web3.eth.Contract(IUniswapV2Pair.abi, this._pairAddress);
    }
}

To reiterate, the "working code" runs the inner code of the async events.Swap() code whenever a swap is triggered, but the same code when implemented as a class does not work. Is this because of the use of classes? Or did I make a mistake somewhere? Thanks in advance!

CodePudding user response:

I fixed the issue. Of course, the issue was outside of the code provided where I defined web3. The working way defined it as:

web3 = new Web3(`wss://polygon-mainnet.g.alchemy.com/v2/${process.env.ALCHEMY_API_KEY}`)

whereas the incorrect class was defining it as

provider = new HDWalletProvider({
            privateKeys: [process.env.DEPLOYMENT_ACCOUNT_KEY],
            providerOrUrl: `wss://polygon-mainnet.g.alchemy.com/v2/${process.env.ALCHEMY_API_KEY}`
        })
web3 = new Web3(provider)
  • Related