My getWeb3.js file:

import Web3 from 'web3'

export default async () => {
    var web3Provider = null;
    if (typeof window.ethereum !== "undefined") {
        web3 = new Web3(window.ethereum)
        try {
            // Request account access if needed
            await window.ethereum.enable()
            // Acccounts now exposed
        } catch (error) {
            // User denied account access...
            console.log("MetaMask cannot be enabled!")
    // Legacy dapp browsers...
    else if (window.web3) {
        web3Provider = new Web3(window.web3.currentProvider);
    // Non-dapp browsers...we use ganache
    else {
        console.log('Non-Ethereum browser detected. You should consider trying MetaMask!');
        web3Provider = new Web3.providers.HttpProvider('http://localhost:7545');
    return web3

Here is how I call getWeb3, it always complain on this var accounts = await this.web3.eth.getAccounts(), saying this.web3.eth is undefined

export default class PaypalContract {
  constructor() {
    if (!instance) {

  instance = this
  this.web3 = getWeb3()
  console.log("web3 init:",this.web3)
  this.contract = contract(PaypalContractMeta)
  this.usdtcontract = contract(usdtContractMeta)

return instance


  async payToContract(coin_address,recipient,price,order_id) {
    //const { eth: { accounts: [ account ] } } = this.web3

var accounts = await this.web3.eth.getAccounts()
var account = accounts[0]
console.log("coin address:",coin_address)
const coincontractInstance = await this.usdtcontract.at(coin_address)
const contractInstance = await this.contract.deployed()
var priceUnit = this.web3.utils.toBN(price).mul(this.web3.utils.toBN(this.web3.utils.toWei("1")))
await coincontractInstance.approve(contractInstance.address,priceUnit,{from: account})
await contractInstance.deposit(coin_address,recipient,priceUnit,order_id,{ from: account })
await contractInstance.setExpiryDate(order_id,0,{ from: account })


3 Answers 3

  1. You are using poor naming conventions. The provider in Web3 is what you use to build a Web3 instance, such as window.web3.currentProvider or window.ethereum.
  2. window.ethereum is not a Web3 instance, it is a Web3 provider. So you have to do: web3Provider = new Web3(window.ethereum);.
  3. When you have a contract, you need to tell it to use the Web3 instance of your choice this.contract.setProvider(this.web3);.
  4. You ought to test if (typeof window.ethereum !== "undefined") { instead.
  5. Also don't ethereum.enable() immediately, but instead do it after your user has done an action that warrants it like "login" or "send a tx". Just loading your page does not warrant it.
  6. Instead of using 10**18, you can use web3.utils.toWei(1).
  7. Don't use Javascript numbers but BN big numbers so that all digits are preserved: var priceUnit = web3.utils.toBN(price).mul(web3.utils.toBN(web3.utils.toWei("1")));.
  8. When you await a contract action like await coincontractInstance.approve(, look into the object that is returned, and in particular the receipt.status to make sure it went through before blindly following on with the next tx.


  • Thank for your advice. After amending accordingly, it still sends the same complain. Oct 15, 2020 at 10:09

This is solved.

I should not use async mode and await in getWeb3, removal of them can solve the problem.


For getting currently connected accounts you need to write,

const web3 = new Web3(window.ethereum);
web3.eth.requestAccounts().then(accounts => console.log(accounts));

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.