0

I have a set of function in my react application which I want to connect to the web3 modal. I use Web3 and web3modal for connecting with different wallets. Here is my code:

    import axios from "axios";
import { useState } from "react";
import Web3 from "web3"; 
import Web3Modal from "web3modal";
import WalletConnectProvider from "@walletconnect/web3-provider";

  
const providerOptions = {
    walletconnect: {
      package: WalletConnectProvider, // required
      options: {
        infuraId: "my_infura_id", // required
        qrcodeModalOptions: {
          mobileLinks: [
            "rainbow",
            "metamask",
            "argent",
            "trust",
            "imtoken",
            "pillar",
          ],
        },
        rpc: { 80001:`https://mainnet.infura.io/v3/my_infura_id`},
        qrcode: true
      },
    },
  };

  const web3Modal = new Web3Modal({
    network: "mainnet", // optional
    theme: "dark", // optional
    cacheProvider: true, // optional
    providerOptions, // required
  });
export const connectWallet = async () => {
    
    try {
        var provider = await web3Modal.connect();
        window.localStorage.setItem("provider", provider); //want to set the provider in localstorage so that I can use it to connect on page refresh and go to new components.
        var web3 = new Web3(provider);
        var accounts = await web3.eth.getAccounts();
        const account= accounts[0];

        return{
          'address': account,
          'provider': provider,
          'status':'success'
        }
    } catch (error) {
        return{
            'address': '',
            'provider': '',
            'status':error
        }
    }
     
        // var web3 = new Web3(providers);
        // var accounts = await web3.eth.getAccounts();
        // // const account= accounts[0];
        // setAccount(accounts[0]);

        // console.log(providers);
}

So what I actually need is to connect to the wallet with the connectwallet function and upon connection i want to store the provider inn the local storage which can be used to connect to the app on page reload.

Now what I actually get is an object which stores in to the local storage. The object looks as follows:

WalletConnectProvider {_events: {…}, _eventsCount: 3, _maxListeners: 30, _blockTracker: PollingBlockTracker, _ready: Stoplight, …}

This object is for the wallet connect and when i Connect to the Metamask I get different provider object.

When I use this object in the front end to connect upon page refresh, it shows the following message:

app.js:243955 Uncaught (in promise) Error: Can't autodetect provider for "[object Object]"

Here is my frontend code to connect on page refresh:

useEffect(async () => {
    
    const provider = window.localStorage.getItem("provider");
  
    if (provider){
      var web3 = new Web3(provider);
      var accounts = await web3.eth.getAccounts();
      
      setAccount(accounts[0]);
      console.log(accounts[0]);
    }else{
      setAccount("");
      console.log('nothing');
    }
  }, []);

Is there anything I am doing wrong. If so please assist me to get it done.

1 Answer 1

0

Thanks for everyone who saw this post and I am not worried that I did not get any response from anyone. So here is the solution which I have figured it out and this was the thing I missed while following the documentation.

useEffect(async () => {
    
    
    const { address,provider, status } = await detectProvider();

    if (status == 'success') {
      setAccount(address);
      setProvider(provider);
      console.log(address);
    } else {
      console.log(status);
    }
  }, [account,provider]);

During the use effect I called a function to check if the cached provider is available in my browser. If cached provider is available it will automatically connect to the wallet provider as below:

export const detectProvider = async () => {
    try {
      if (web3Modal.cachedProvider) {
        return connectWallet();
      }else{
        return{
          'address': '',
          'provider': '',
          'status':'error'
        }
      }
      
    } catch (error) {
        return{
            'provider': null,
            'status':error
        }
    }
}

The ConnectWalet is as follow:

export const connectWallet = async () => {
    
    try {
        var provider = await web3Modal.connect();
        // console.log(provider);
        var web3 = new Web3(provider);
        var accounts = await web3.eth.getAccounts();
        const account= accounts[0];

        return{
          'address': account,
          'provider': provider,
          'status':'success'
        }
    } catch (error) {
        return{
            'address': '',
            'provider': '',
            'status':error
        }
    }
}

So this connectwallet function I am calling when the wallet connect button is pressed and also when the page refreshes. When the function is called at first it will prombt for the wallet to be selected and when it is called on page refresh it will not prombt the wallet and instead it takes the provider from the cache and connects automatically.

This answer may help someone in future who faces the similar issue.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.