Home > OS >  How to fire EthersJS *.on events?
How to fire EthersJS *.on events?

Time:02-25

I am working on a react app with redux. I did implement thunk actions to:

  1. Create a web3modal instance
  2. Register a ethersjs provider
  3. Register a ethersjs signer

Everything is very basic and simple. However whenever I try to make use of the on events (doesn't matter if provider oder contract), they simply won't fire.

I have 2 files:

  1. walletSlice.ts which will handle all the redux action and reducer logic with @reduxjs/toolkit .
  2. wallet-api.ts which has all the relevant functions to interact with the wallet.

The walletSlice.ts relevant part looks exactly like this:

export const connectWallet = createAsyncThunk(
  'web3wallet/connectWallet',
  async (arg, thunkApi) => {
    const instance = await WalletAPI.registerWalletInstance();
    provider = await WalletAPI.registerWalletProvider(instance);
    signer = await WalletAPI.registerWalletSigner(provider);
   
    return Promise.resolve();
  }
);

The wallet-api.ts relevant parts look exactly like this:

import { ethers, providers } from 'ethers';
import Web3Modal from 'web3modal';

// get Web3Modal Instance
export async function registerWalletInstance(): Promise<Web3Modal> {
  const providerOptions = {};

  const web3Modal = new Web3Modal({
    providerOptions,
  });
  const instance = await web3Modal.connect();

  return Promise.resolve(instance);
}

/**
 * register Wallet provider.
 * Events on provider @see https://docs.ethers.io/v5/api/providers/provider/#Provider--event-methods
 * Implementing the EIP-1193 Standard @see https://eips.ethereum.org/EIPS/eip-1193
 */
export async function registerWalletProvider(
  instance: any
): Promise<providers.JsonRpcProvider> {
  const provider = new ethers.providers.Web3Provider(instance);

  // Subscribe to accounts change
  provider.on('accountsChanged', (accounts: string[]) => {
    console.log(accounts);
  });

  // Subscribe to chainId change
  provider.on('chainChanged', (chainId: number) => {
    console.log(chainId);
  });

  // Subscribe to provider connection
  provider.on('connect', (info: { chainId: number }) => {
    console.log(info);
  });

  // Subscribe to provider disconnection
  provider.on('disconnect', (error: { code: number; message: string }) => {
    console.log(error);
  });

  provider.on('error', (tx) => {
    // Emitted when any error occurs
    console.log({ tx });
  });

  return Promise.resolve(provider);
}

// register Wallet signer.
export async function registerWalletSigner(
  provider: providers.JsonRpcProvider
): Promise<providers.JsonRpcSigner> {
  const signer = provider.getSigner();
  return Promise.resolve(signer);
}

None of the provider.on() events will fire. I've tried to change networks from rinkeby to polygon or mainnet, but nothing happens. When I disconnect from the site, nothing happens. It is the same with all provider events as shown in wallet-api.ts. I did try the same approach with another file called contract-api.ts. However the contract events won't fire either.

I tried to use the provider.on() events with useEffect() or useCallback(). Moved the code to a standalone tsx. But nothing happened.

At this point I am pretty lost. Any help is much appreciated.

CodePudding user response:

await web3Modal.connect() already returns a provider; try to use that one instead of new ethers.providers.Web3Provider(instance);

  • Related