web3modal icon indicating copy to clipboard operation
web3modal copied to clipboard

WalletConnect - Provider not set or invalid

Open CryptoCarlos21 opened this issue 2 years ago • 0 comments

I'm having issues running this web3modal for mobile interaction via WalletConnect.

Desktop Metamask/Coinbase works etc it's simply when I use the QR code and log in using WalletConnect that I can't run any functions.

It pulls the correct address and displays as expected but when I try to use the provider I get the error

Uncaught (in promise) Error: Provider not set or invalid

The function that is running as a test is:

//variables from previous parts of the code:
const contract_address = "xxx";
var contractInterface = new web3.eth.Contract(ABI, contract_address)
const ABI = myABI is here


export const eatBeans = async () => {
  
  let address = selectedAccount
  if (address) {
      await contractInterface.methods.eatBeans().send({ from: address })
      await fetchAccountData()
  }
}  

the full code is here


import React from "react";
import {
  chakra,
  Box,
  Flex,
  useColorModeValue,
  VisuallyHidden,
  HStack,
  useDisclosure,
  VStack,
  IconButton,
  CloseButton,
  useColorMode,
  Avatar,
  Button,
} from "@chakra-ui/react";

import { AiOutlineMenu } from "react-icons/ai";
import { FaMoon, FaSun } from "react-icons/fa";
import Web3EthContract from "web3-eth-contract";
import Web3 from "web3";

import Web3Modal from "web3modal";
import WalletConnectProvider from "@walletconnect/web3-provider";
import WalletLink from "walletlink";
//const EvmChains = window.EvmChains;

const INFURA_ID = "XXXX";

const providerOptions = {
  walletconnect: {
      package: WalletConnectProvider, // required
      options: {
          infuraId: INFURA_ID, // required
          rpc: {
              56: "https://bsc-dataseed.binance.org/", 
          },
      },
  },
  walletlink: {
      package: WalletLink, // Required
      options: {
          appName: "XXXX", // Required
          infuraId: "", // Required unless you provide a JSON RPC url; see `rpc` below
          rpc: "https://bsc-dataseed.binance.org/", // Optional if `infuraId` is provided; otherwise it's required
          chainId: 56, // Optional. It defaults to 1 if not provided
          appLogoUrl: null, // Optional. Application logo image URL. favicon is used if unspecified
          darkMode: true, // Optional. Use dark theme, defaults to false
      },
  },
};
let provider 
const web3 = new Web3(Web3.provider);


// Chosen wallet provider given by the dialog window



// Address of the selected account
let selectedAccount;
const web3Modal = new Web3Modal({
  network: "mainnet", // optional
  cacheProvider: false, // optional
  providerOptions, // required
});



console.log("Initializing example");
  console.log("WalletConnectProvider is", WalletConnectProvider);

 


  


async function fetchAccountData() {
  const provider = await web3Modal.connect();
            const web3 = new Web3(provider);
            console.log("web", web3);

            Web3EthContract.setProvider(provider);
  console.log("Web3 from FetchAccountData worked", web3);
 console.log("Refresh account data provider = " + await provider)

  if (window.ethereum) {
    try {
      // check if the chain to connect to is installed
      await window.ethereum.request({
        method: 'wallet_switchEthereumChain',
        params: [{ chainId: '0x38' }], // chainId must be in hexadecimal numbers
      });
    } catch (error) {
      // This error code indicates that the chain has not been added to MetaMask
      // if it is not, then install it into the user MetaMask
      if (error.code === 4902) {
        try {
          await window.ethereum.request({
            method: 'wallet_addEthereumChain',
            params: [
              {
                chainId: '0x38',
                rpcUrl: 'https://bsc-dataseed.binance.org/',
              },
            ],
          });
        } catch (addError) {
          console.error(addError);
        }
      }
      console.error(error);
    }
  } else {
    // if no window.ethereum then MetaMask is not installed
    console.log('no window.ethereum then MetaMask is not installed');
  } 
  
  // Get list of accounts of the connected wallet
  const accounts = await web3.eth.getAccounts();

  // MetaMask does not give you all accounts, only the selected account
  console.log("Got accounts", accounts);
  selectedAccount = accounts[0];

  document.querySelector("#selected-account").textContent = selectedAccount;

  // Get a handl
  //const template = document.querySelector("#template-balance");

  // Purge UI elements any previously loaded accounts

  // Go through all accounts and get their ETH balance
  const rowResolvers = accounts.map(async (address) => {
    const balance = await web3.eth.getBalance(address);
    // ethBalance is a BigNumber instance
    // https://github.com/indutny/bn.js/
    const ethBalance = web3.utils.fromWei(balance, "ether");
    const humanFriendlyBalance = parseFloat(ethBalance).toFixed(4);
    // Fill in the templated row and put in the document
    //clone.querySelector(".address").textContent = address;
    document.querySelector(".balance").textContent = humanFriendlyBalance;
    //accountContainer.appendChild(clone);
  });

  // Because rendering account does its own RPC commucation
  // with Ethereum node, we do not want to display any results
  // until data for all accounts is loaded
  await Promise.all(rowResolvers);

  // Display fully loaded UI for wallet data
  if(document.querySelector("#prepare")){
  document.querySelector("#prepare").style.display = "none";
  document.querySelector("#connected").style.display = "block";
  document.querySelector("#templates").style.display = "block";
  }
}



/**
 * Fetch account data for UI when
 * - User switches accounts in wallet
 * - User switches networks in wallet
 * - User connects wallet initially
 */
 const  refreshAccountData = async () => {
  // const provider = await web3Modal.connect();
  //     const web3 = new Web3(provider);
  //     console.log("web loaded from refresh data", web3);

  //     Web3EthContract.setProvider(provider);
  // If any current data is displayed when
  // the user is switching acounts in the wallet
  // immediate hide this data
  if( document.querySelector("#connected") ){
  document.querySelector("#connected").style.display = "none";
  document.querySelector("#prepare").style.display = "block";
  }
  // Disable button while UI is loading.
  // fetchAccountData() will take a while as it communicates
  // with Ethereum node via JSON-RPC and loads chain data
  // over an API call.
  if(document.querySelector("#btn-connect")){
  document.querySelector("#btn-connect").setAttribute("disabled", "disabled")
  await fetchAccountData(provider);
  document.querySelector("#btn-connect").removeAttribute("disabled")
  }
}


/**
 * Connect wallet button pressed.
 */
 async function onConnect() {

  console.log("Opening a dialog", web3Modal);
  try {
    provider = await web3Modal.connect();
  } catch(e) {
    console.log("Could not get a wallet connection", e);
    return;
  }

  // Subscribe to accounts change
  provider.on("accountsChanged", (accounts) => {
    fetchAccountData();
  });

  // Subscribe to chainId change
  provider.on("chainChanged", (chainId) => {
    fetchAccountData();
  });

  // Subscribe to networkId change
  provider.on("networkChanged", (networkId) => {
    fetchAccountData();
  });

  await refreshAccountData();
}

/**
 * Disconnect wallet button pressed.
 */
async function onDisconnect() {

  console.log("Killing the wallet connection", provider);

  // TODO: Which providers have close method?
  if(provider.close) {
    await provider.close();

    // If the cached provider is not cleared,
    // WalletConnect will default to the existing session
    // and does not allow to re-scan the QR code with a new wallet.
    // Depending on your use case you may want or want not his behavir.
    await web3Modal.clearCachedProvider();
    provider = null;
  }

  selectedAccount = null;

  // Set the UI back to the initial state
  if(document.querySelector("#prepare")){document.querySelector("#prepare").style.display = "block";
  document.querySelector("#connected").style.display = "none";
}
}
//custom functions
const contract_address = "XXXX";
const ABI = [XXXX]
var contractInterface = new web3.eth.Contract(ABI, contract_address)
export const eatBeans = async () => {
  
  let address = selectedAccount
  if (address) {
      await contractInterface.methods.eatBeans().send({ from: address })
      await fetchAccountData()
  }
}  

export default function Navbar() {
  
  const color = useColorModeValue("dark", "light");
  const bg = useColorModeValue("white", "gray.800");
  const mobileNav = useDisclosure();
  const size = "96px";
  const { toggleColorMode: toggleMode } = useColorMode();
  const text = useColorModeValue("dark", "light");
  const SwitchIcon = useColorModeValue(FaMoon, FaSun);
 
  
  // Button bgColor
  const bgColor = useColorModeValue("blue.200", "blue.500");
 


  return (
    <Box shadow="2xl" borderRadius="3xl">
      
          <div id="prepare">
            <Button className="btn btn-primary" id="btn-connect" onClick={(e)=> {onConnect()}}>   
              Connect wallet
            </Button>
          </div>
          <div id="connected" style={{display: 'none' }}>
            <Button className="btn btn-primary" id="btn-connect" onClick={(e)=> {onDisconnect()}}>
              Disconnect wallet
            </Button>
          </div>
          <div id="network" style={{display: 'none' }}>
              <p>
                <strong>Selected account:</strong> <span id="selected-account"></span>
              </p>

            </div>        
           
    </Box>
  );
}



CryptoCarlos21 avatar May 12 '22 16:05 CryptoCarlos21