Search code examples
reactjsblockchainsoliditysmartcontractsmetamask

Metamask RPC methods do not exist


I have been following a tutorial on how to create my first Web3js application with solidity and react.
The tutorial was going great until I fall into this problem with metamask RPC.
The tutorial I have been following is this: https://www.youtube.com/watch?v=Wn_Kb3MR_cU&t=6333s&ab_channel=JavaScriptMastery
Right now I'm getting the following errors when trying to run function from ethereum:

inpage.js:1 MetaMask - RPC Error: The method "accounts " does not exist / is not available.

inpage.js:1 MetaMask - RPC Error: The method "eth_accounts " does not exist / is not available. 

uncaught (in promise) {code: -32601, message: 'The method "eth_accounts " does not exist / is not available.', data: {…}, stack: '{\n  "code": -32601,\n  "message": "The method \\"eth…beogaeaoehlefnkodbefgpgknn/common-0.js:18:167275)'}

uncaught (in promise) {code: -32601, message: 'The method "eth_requestAccounts " does not exist / is not available.', data: {…}, stack: '{\n  "code": -32601,\n  "message": "The method \\"eth…beogaeaoehlefnkodbefgpgknn/common-0.js:18:167275)'}

The file that runs this is a context file TransactionContext.tsx:

import React, { useEffect, useState } from 'react';
import { ethers } from 'ethers';
import { contractABI, contractAddress } from '../utils/constants';

export const TransactionContext = React.createContext({} as any);

const { ethereum } = window as any;

const getEthereumContract = () => {
    const provider = new ethers.providers.Web3Provider(ethereum);
    const signer = provider.getSigner();
    const transactionsContract = new ethers.Contract(contractAddress, contractABI, signer);

    console.log({
        provider,
        signer,
        transactionsContract
    })
}

export const TransactionProvider = ({ children }: any) => {

    const [currentAccount, setCurrentAccount] = useState('');

    const checkIfWalletIsConnected = async () => {
        if (!ethereum) return alert("Please install metamask!");

        const accounts = await ethereum.request({ method: 'eth_accounts '});

        console.log(accounts);
    }

    const connectWallet = async () => {
        try {
            if (!ethereum) return alert("Please install metamask!");
            const accounts = await ethereum.request({ method: 'eth_requestAccounts '});
            setCurrentAccount(accounts[0]);
        } catch (e) {
            console.log(e);
            throw new Error('No Ethereum object.')
        }
    }

    useEffect(() => {
        checkIfWalletIsConnected();
    }, [])

    return (
        <TransactionContext.Provider value={{ connectWallet }}>
            {children}
        </TransactionContext.Provider>
    )
}

Solution

  • I see 3 issues in your contract:

    1- you are not returning the contract from getEthereumContract. it should be

    const getEthereumContract = () => {
        const provider = new ethers.providers.Web3Provider(ethereum);
        const signer = provider.getSigner();
        const transactionsContract = new ethers.Contract(contractAddress, contractABI, signer);
    
        return transactionsContract
    }
    

    I dont see you are using here yet but you might get bug in the future:

    2- Error says 'The method "eth_accounts " does not exist ... you have extra space here "eth_accounts ". should be

     const accounts = await ethereum.request({ method: 'eth_accounts'});
    

    3- this is similar to second. You have extra space

     const accounts = await ethereum.request({ method: 'eth_requestAccounts'});